| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 return x < 0; | 74 return x < 0; |
| 75 } | 75 } |
| 76 } | 76 } |
| 77 } // namespace std | 77 } // namespace std |
| 78 #endif // signbit | 78 #endif // signbit |
| 79 | 79 |
| 80 namespace v8 { | 80 namespace v8 { |
| 81 namespace internal { | 81 namespace internal { |
| 82 | 82 |
| 83 | 83 |
| 84 static Mutex* limit_mutex = NULL; | |
| 85 | |
| 86 | |
| 87 const char* OS::LocalTimezone(double time) { | 84 const char* OS::LocalTimezone(double time) { |
| 88 if (std::isnan(time)) return ""; | 85 if (std::isnan(time)) return ""; |
| 89 time_t tv = static_cast<time_t>(floor(time/msPerSecond)); | 86 time_t tv = static_cast<time_t>(floor(time/msPerSecond)); |
| 90 struct tm* t = localtime(&tv); | 87 struct tm* t = localtime(&tv); |
| 91 if (NULL == t) return ""; | 88 if (NULL == t) return ""; |
| 92 return tzname[0]; // The location of the timezone string on Solaris. | 89 return tzname[0]; // The location of the timezone string on Solaris. |
| 93 } | 90 } |
| 94 | 91 |
| 95 | 92 |
| 96 double OS::LocalTimeOffset() { | 93 double OS::LocalTimeOffset() { |
| 97 tzset(); | 94 tzset(); |
| 98 return -static_cast<double>(timezone * msPerSecond); | 95 return -static_cast<double>(timezone * msPerSecond); |
| 99 } | 96 } |
| 100 | 97 |
| 101 | 98 |
| 102 // We keep the lowest and highest addresses mapped as a quick way of | |
| 103 // determining that pointers are outside the heap (used mostly in assertions | |
| 104 // and verification). The estimate is conservative, i.e., not all addresses in | |
| 105 // 'allocated' space are actually allocated to our heap. The range is | |
| 106 // [lowest, highest), inclusive on the low and and exclusive on the high end. | |
| 107 static void* lowest_ever_allocated = reinterpret_cast<void*>(-1); | |
| 108 static void* highest_ever_allocated = reinterpret_cast<void*>(0); | |
| 109 | |
| 110 | |
| 111 static void UpdateAllocatedSpaceLimits(void* address, int size) { | |
| 112 ASSERT(limit_mutex != NULL); | |
| 113 LockGuard<Mutex> lock_guard(limit_mutex); | |
| 114 | |
| 115 lowest_ever_allocated = Min(lowest_ever_allocated, address); | |
| 116 highest_ever_allocated = | |
| 117 Max(highest_ever_allocated, | |
| 118 reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size)); | |
| 119 } | |
| 120 | |
| 121 | |
| 122 bool OS::IsOutsideAllocatedSpace(void* address) { | |
| 123 return address < lowest_ever_allocated || address >= highest_ever_allocated; | |
| 124 } | |
| 125 | |
| 126 | |
| 127 void* OS::Allocate(const size_t requested, | 99 void* OS::Allocate(const size_t requested, |
| 128 size_t* allocated, | 100 size_t* allocated, |
| 129 bool is_executable) { | 101 bool is_executable) { |
| 130 const size_t msize = RoundUp(requested, getpagesize()); | 102 const size_t msize = RoundUp(requested, getpagesize()); |
| 131 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); | 103 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); |
| 132 void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0); | 104 void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0); |
| 133 | 105 |
| 134 if (mbase == MAP_FAILED) { | 106 if (mbase == MAP_FAILED) { |
| 135 LOG(ISOLATE, StringEvent("OS::Allocate", "mmap failed")); | 107 LOG(ISOLATE, StringEvent("OS::Allocate", "mmap failed")); |
| 136 return NULL; | 108 return NULL; |
| 137 } | 109 } |
| 138 *allocated = msize; | 110 *allocated = msize; |
| 139 UpdateAllocatedSpaceLimits(mbase, msize); | |
| 140 return mbase; | 111 return mbase; |
| 141 } | 112 } |
| 142 | 113 |
| 143 | 114 |
| 144 void OS::DumpBacktrace() { | 115 void OS::DumpBacktrace() { |
| 145 // Currently unsupported. | 116 // Currently unsupported. |
| 146 } | 117 } |
| 147 | 118 |
| 148 | 119 |
| 149 class PosixMemoryMappedFile : public OS::MemoryMappedFile { | 120 class PosixMemoryMappedFile : public OS::MemoryMappedFile { |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { | 330 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { |
| 360 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); | 331 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); |
| 361 if (MAP_FAILED == mmap(base, | 332 if (MAP_FAILED == mmap(base, |
| 362 size, | 333 size, |
| 363 prot, | 334 prot, |
| 364 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | 335 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, |
| 365 kMmapFd, | 336 kMmapFd, |
| 366 kMmapFdOffset)) { | 337 kMmapFdOffset)) { |
| 367 return false; | 338 return false; |
| 368 } | 339 } |
| 369 | |
| 370 UpdateAllocatedSpaceLimits(base, size); | |
| 371 return true; | 340 return true; |
| 372 } | 341 } |
| 373 | 342 |
| 374 | 343 |
| 375 bool VirtualMemory::UncommitRegion(void* base, size_t size) { | 344 bool VirtualMemory::UncommitRegion(void* base, size_t size) { |
| 376 return mmap(base, | 345 return mmap(base, |
| 377 size, | 346 size, |
| 378 PROT_NONE, | 347 PROT_NONE, |
| 379 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED, | 348 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED, |
| 380 kMmapFd, | 349 kMmapFd, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 394 | 363 |
| 395 | 364 |
| 396 void OS::SetUp() { | 365 void OS::SetUp() { |
| 397 // Seed the random number generator. | 366 // Seed the random number generator. |
| 398 // Convert the current time to a 64-bit integer first, before converting it | 367 // Convert the current time to a 64-bit integer first, before converting it |
| 399 // to an unsigned. Going directly will cause an overflow and the seed to be | 368 // to an unsigned. Going directly will cause an overflow and the seed to be |
| 400 // set to all ones. The seed will be identical for different instances that | 369 // set to all ones. The seed will be identical for different instances that |
| 401 // call this setup code within the same millisecond. | 370 // call this setup code within the same millisecond. |
| 402 uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); | 371 uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); |
| 403 srandom(static_cast<unsigned int>(seed)); | 372 srandom(static_cast<unsigned int>(seed)); |
| 404 limit_mutex = new Mutex(); | |
| 405 } | 373 } |
| 406 | 374 |
| 407 | 375 |
| 408 void OS::TearDown() { | 376 void OS::TearDown() { |
| 409 delete limit_mutex; | |
| 410 } | 377 } |
| 411 | 378 |
| 412 | 379 |
| 413 } } // namespace v8::internal | 380 } } // namespace v8::internal |
| OLD | NEW |