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 |