| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 __attribute__((weak_import)); | 72 __attribute__((weak_import)); |
| 73 extern void backtrace_symbols_fd(void* const*, int, int) | 73 extern void backtrace_symbols_fd(void* const*, int, int) |
| 74 __attribute__((weak_import)); | 74 __attribute__((weak_import)); |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 namespace v8 { | 78 namespace v8 { |
| 79 namespace internal { | 79 namespace internal { |
| 80 | 80 |
| 81 | 81 |
| 82 // Constants used for mmap. | |
| 83 // kMmapFd is used to pass vm_alloc flags to tag the region with the user | |
| 84 // defined tag 255 This helps identify V8-allocated regions in memory analysis | |
| 85 // tools like vmmap(1). | |
| 86 static const int kMmapFd = VM_MAKE_TAG(255); | |
| 87 static const off_t kMmapFdOffset = 0; | |
| 88 | |
| 89 | |
| 90 void* OS::Allocate(const size_t requested, | |
| 91 size_t* allocated, | |
| 92 bool is_executable) { | |
| 93 const size_t msize = RoundUp(requested, getpagesize()); | |
| 94 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); | |
| 95 void* mbase = mmap(OS::GetRandomMmapAddr(), | |
| 96 msize, | |
| 97 prot, | |
| 98 MAP_PRIVATE | MAP_ANON, | |
| 99 kMmapFd, | |
| 100 kMmapFdOffset); | |
| 101 if (mbase == MAP_FAILED) { | |
| 102 LOG(Isolate::Current(), StringEvent("OS::Allocate", "mmap failed")); | |
| 103 return NULL; | |
| 104 } | |
| 105 *allocated = msize; | |
| 106 return mbase; | |
| 107 } | |
| 108 | |
| 109 | |
| 110 void OS::DumpBacktrace() { | 82 void OS::DumpBacktrace() { |
| 111 // If weak link to execinfo lib has failed, ie because we are on 10.4, abort. | 83 // If weak link to execinfo lib has failed, ie because we are on 10.4, abort. |
| 112 if (backtrace == NULL) return; | 84 if (backtrace == NULL) return; |
| 113 | 85 |
| 114 POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace(); | 86 POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace(); |
| 115 } | 87 } |
| 116 | 88 |
| 117 | 89 |
| 118 class PosixMemoryMappedFile : public OS::MemoryMappedFile { | 90 class PosixMemoryMappedFile : public OS::MemoryMappedFile { |
| 119 public: | 91 public: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 130 | 102 |
| 131 | 103 |
| 132 OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { | 104 OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { |
| 133 FILE* file = fopen(name, "r+"); | 105 FILE* file = fopen(name, "r+"); |
| 134 if (file == NULL) return NULL; | 106 if (file == NULL) return NULL; |
| 135 | 107 |
| 136 fseek(file, 0, SEEK_END); | 108 fseek(file, 0, SEEK_END); |
| 137 int size = ftell(file); | 109 int size = ftell(file); |
| 138 | 110 |
| 139 void* memory = | 111 void* memory = |
| 140 mmap(OS::GetRandomMmapAddr(), | 112 mmap(NULL, |
| 141 size, | 113 size, |
| 142 PROT_READ | PROT_WRITE, | 114 PROT_READ | PROT_WRITE, |
| 143 MAP_SHARED, | 115 MAP_SHARED, |
| 144 fileno(file), | 116 fileno(file), |
| 145 0); | 117 0); |
| 146 return new PosixMemoryMappedFile(file, memory, size); | 118 return new PosixMemoryMappedFile(file, memory, size); |
| 147 } | 119 } |
| 148 | 120 |
| 149 | 121 |
| 150 OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, | 122 OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, |
| 151 void* initial) { | 123 void* initial) { |
| 152 FILE* file = fopen(name, "w+"); | 124 FILE* file = fopen(name, "w+"); |
| 153 if (file == NULL) return NULL; | 125 if (file == NULL) return NULL; |
| 154 int result = fwrite(initial, size, 1, file); | 126 int result = fwrite(initial, size, 1, file); |
| 155 if (result < 1) { | 127 if (result < 1) { |
| 156 fclose(file); | 128 fclose(file); |
| 157 return NULL; | 129 return NULL; |
| 158 } | 130 } |
| 159 void* memory = | 131 void* memory = |
| 160 mmap(OS::GetRandomMmapAddr(), | 132 mmap(NULL, |
| 161 size, | 133 size, |
| 162 PROT_READ | PROT_WRITE, | 134 PROT_READ | PROT_WRITE, |
| 163 MAP_SHARED, | 135 MAP_SHARED, |
| 164 fileno(file), | 136 fileno(file), |
| 165 0); | 137 0); |
| 166 return new PosixMemoryMappedFile(file, memory, size); | 138 return new PosixMemoryMappedFile(file, memory, size); |
| 167 } | 139 } |
| 168 | 140 |
| 169 | 141 |
| 170 PosixMemoryMappedFile::~PosixMemoryMappedFile() { | 142 PosixMemoryMappedFile::~PosixMemoryMappedFile() { |
| 171 if (memory_) OS::Free(memory_, size_); | 143 if (memory_) munmap(memory_, size_); |
| 172 fclose(file_); | 144 fclose(file_); |
| 173 } | 145 } |
| 174 | 146 |
| 175 | 147 |
| 176 void OS::LogSharedLibraryAddresses() { | 148 void OS::LogSharedLibraryAddresses() { |
| 177 unsigned int images_count = _dyld_image_count(); | 149 unsigned int images_count = _dyld_image_count(); |
| 178 for (unsigned int i = 0; i < images_count; ++i) { | 150 for (unsigned int i = 0; i < images_count; ++i) { |
| 179 const mach_header* header = _dyld_get_image_header(i); | 151 const mach_header* header = _dyld_get_image_header(i); |
| 180 if (header == NULL) continue; | 152 if (header == NULL) continue; |
| 181 #if V8_HOST_ARCH_X64 | 153 #if V8_HOST_ARCH_X64 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 } | 192 } |
| 221 | 193 |
| 222 | 194 |
| 223 int OS::StackWalk(Vector<StackFrame> frames) { | 195 int OS::StackWalk(Vector<StackFrame> frames) { |
| 224 // If weak link to execinfo lib has failed, ie because we are on 10.4, abort. | 196 // If weak link to execinfo lib has failed, ie because we are on 10.4, abort. |
| 225 if (backtrace == NULL) return 0; | 197 if (backtrace == NULL) return 0; |
| 226 | 198 |
| 227 return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames); | 199 return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames); |
| 228 } | 200 } |
| 229 | 201 |
| 230 | |
| 231 VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } | |
| 232 | |
| 233 | |
| 234 VirtualMemory::VirtualMemory(size_t size) | |
| 235 : address_(ReserveRegion(size)), size_(size) { } | |
| 236 | |
| 237 | |
| 238 VirtualMemory::VirtualMemory(size_t size, size_t alignment) | |
| 239 : address_(NULL), size_(0) { | |
| 240 ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment()))); | |
| 241 size_t request_size = RoundUp(size + alignment, | |
| 242 static_cast<intptr_t>(OS::AllocateAlignment())); | |
| 243 void* reservation = mmap(OS::GetRandomMmapAddr(), | |
| 244 request_size, | |
| 245 PROT_NONE, | |
| 246 MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, | |
| 247 kMmapFd, | |
| 248 kMmapFdOffset); | |
| 249 if (reservation == MAP_FAILED) return; | |
| 250 | |
| 251 Address base = static_cast<Address>(reservation); | |
| 252 Address aligned_base = RoundUp(base, alignment); | |
| 253 ASSERT_LE(base, aligned_base); | |
| 254 | |
| 255 // Unmap extra memory reserved before and after the desired block. | |
| 256 if (aligned_base != base) { | |
| 257 size_t prefix_size = static_cast<size_t>(aligned_base - base); | |
| 258 OS::Free(base, prefix_size); | |
| 259 request_size -= prefix_size; | |
| 260 } | |
| 261 | |
| 262 size_t aligned_size = RoundUp(size, OS::AllocateAlignment()); | |
| 263 ASSERT_LE(aligned_size, request_size); | |
| 264 | |
| 265 if (aligned_size != request_size) { | |
| 266 size_t suffix_size = request_size - aligned_size; | |
| 267 OS::Free(aligned_base + aligned_size, suffix_size); | |
| 268 request_size -= suffix_size; | |
| 269 } | |
| 270 | |
| 271 ASSERT(aligned_size == request_size); | |
| 272 | |
| 273 address_ = static_cast<void*>(aligned_base); | |
| 274 size_ = aligned_size; | |
| 275 } | |
| 276 | |
| 277 | |
| 278 VirtualMemory::~VirtualMemory() { | |
| 279 if (IsReserved()) { | |
| 280 bool result = ReleaseRegion(address(), size()); | |
| 281 ASSERT(result); | |
| 282 USE(result); | |
| 283 } | |
| 284 } | |
| 285 | |
| 286 | |
| 287 bool VirtualMemory::IsReserved() { | |
| 288 return address_ != NULL; | |
| 289 } | |
| 290 | |
| 291 | |
| 292 void VirtualMemory::Reset() { | |
| 293 address_ = NULL; | |
| 294 size_ = 0; | |
| 295 } | |
| 296 | |
| 297 | |
| 298 bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { | |
| 299 return CommitRegion(address, size, is_executable); | |
| 300 } | |
| 301 | |
| 302 | |
| 303 bool VirtualMemory::Uncommit(void* address, size_t size) { | |
| 304 return UncommitRegion(address, size); | |
| 305 } | |
| 306 | |
| 307 | |
| 308 bool VirtualMemory::Guard(void* address) { | |
| 309 OS::Guard(address, OS::CommitPageSize()); | |
| 310 return true; | |
| 311 } | |
| 312 | |
| 313 | |
| 314 void* VirtualMemory::ReserveRegion(size_t size) { | |
| 315 void* result = mmap(OS::GetRandomMmapAddr(), | |
| 316 size, | |
| 317 PROT_NONE, | |
| 318 MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, | |
| 319 kMmapFd, | |
| 320 kMmapFdOffset); | |
| 321 | |
| 322 if (result == MAP_FAILED) return NULL; | |
| 323 | |
| 324 return result; | |
| 325 } | |
| 326 | |
| 327 | |
| 328 bool VirtualMemory::CommitRegion(void* address, | |
| 329 size_t size, | |
| 330 bool is_executable) { | |
| 331 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); | |
| 332 if (MAP_FAILED == mmap(address, | |
| 333 size, | |
| 334 prot, | |
| 335 MAP_PRIVATE | MAP_ANON | MAP_FIXED, | |
| 336 kMmapFd, | |
| 337 kMmapFdOffset)) { | |
| 338 return false; | |
| 339 } | |
| 340 return true; | |
| 341 } | |
| 342 | |
| 343 | |
| 344 bool VirtualMemory::UncommitRegion(void* address, size_t size) { | |
| 345 return mmap(address, | |
| 346 size, | |
| 347 PROT_NONE, | |
| 348 MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED, | |
| 349 kMmapFd, | |
| 350 kMmapFdOffset) != MAP_FAILED; | |
| 351 } | |
| 352 | |
| 353 | |
| 354 bool VirtualMemory::ReleaseRegion(void* address, size_t size) { | |
| 355 return munmap(address, size) == 0; | |
| 356 } | |
| 357 | |
| 358 | |
| 359 bool VirtualMemory::HasLazyCommits() { | |
| 360 return false; | |
| 361 } | |
| 362 | |
| 363 } } // namespace v8::internal | 202 } } // namespace v8::internal |
| OLD | NEW |