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> |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 const size_t msize = RoundUp(requested, AllocateAlignment()); | 135 const size_t msize = RoundUp(requested, AllocateAlignment()); |
136 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); | 136 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); |
137 void* addr = OS::GetRandomMmapAddr(); | 137 void* addr = OS::GetRandomMmapAddr(); |
138 void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 138 void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
139 if (mbase == MAP_FAILED) return NULL; | 139 if (mbase == MAP_FAILED) return NULL; |
140 *allocated = msize; | 140 *allocated = msize; |
141 return mbase; | 141 return mbase; |
142 } | 142 } |
143 | 143 |
144 | 144 |
145 class PosixMemoryMappedFile : public OS::MemoryMappedFile { | |
146 public: | |
147 PosixMemoryMappedFile(FILE* file, void* memory, int size) | |
148 : file_(file), memory_(memory), size_(size) { } | |
149 virtual ~PosixMemoryMappedFile(); | |
150 virtual void* memory() { return memory_; } | |
151 virtual int size() { return size_; } | |
152 private: | |
153 FILE* file_; | |
154 void* memory_; | |
155 int size_; | |
156 }; | |
157 | |
158 | |
159 OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { | |
160 FILE* file = fopen(name, "r+"); | |
161 if (file == NULL) return NULL; | |
162 | |
163 fseek(file, 0, SEEK_END); | |
164 int size = ftell(file); | |
165 | |
166 void* memory = | |
167 mmap(OS::GetRandomMmapAddr(), | |
168 size, | |
169 PROT_READ | PROT_WRITE, | |
170 MAP_SHARED, | |
171 fileno(file), | |
172 0); | |
173 return new PosixMemoryMappedFile(file, memory, size); | |
174 } | |
175 | |
176 | |
177 OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, | |
178 void* initial) { | |
179 FILE* file = fopen(name, "w+"); | |
180 if (file == NULL) return NULL; | |
181 int result = fwrite(initial, size, 1, file); | |
182 if (result < 1) { | |
183 fclose(file); | |
184 return NULL; | |
185 } | |
186 void* memory = | |
187 mmap(OS::GetRandomMmapAddr(), | |
188 size, | |
189 PROT_READ | PROT_WRITE, | |
190 MAP_SHARED, | |
191 fileno(file), | |
192 0); | |
193 return new PosixMemoryMappedFile(file, memory, size); | |
194 } | |
195 | |
196 | |
197 PosixMemoryMappedFile::~PosixMemoryMappedFile() { | |
198 if (memory_) OS::Free(memory_, size_); | |
199 fclose(file_); | |
200 } | |
201 | |
202 | |
203 std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() { | 145 std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() { |
204 std::vector<SharedLibraryAddress> result; | 146 std::vector<SharedLibraryAddress> result; |
205 // This function assumes that the layout of the file is as follows: | 147 // This function assumes that the layout of the file is as follows: |
206 // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name] | 148 // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name] |
207 // If we encounter an unexpected situation we abort scanning further entries. | 149 // If we encounter an unexpected situation we abort scanning further entries. |
208 FILE* fp = fopen("/proc/self/maps", "r"); | 150 FILE* fp = fopen("/proc/self/maps", "r"); |
209 if (fp == NULL) return result; | 151 if (fp == NULL) return result; |
210 | 152 |
211 // Allocate enough room to be able to store a full file name. | 153 // Allocate enough room to be able to store a full file name. |
212 const int kLibNameLen = FILENAME_MAX + 1; | 154 const int kLibNameLen = FILENAME_MAX + 1; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 | 206 |
265 void OS::SignalCodeMovingGC() { | 207 void OS::SignalCodeMovingGC() { |
266 // Support for ll_prof.py. | 208 // Support for ll_prof.py. |
267 // | 209 // |
268 // The Linux profiler built into the kernel logs all mmap's with | 210 // The Linux profiler built into the kernel logs all mmap's with |
269 // PROT_EXEC so that analysis tools can properly attribute ticks. We | 211 // PROT_EXEC so that analysis tools can properly attribute ticks. We |
270 // do a mmap with a name known by ll_prof.py and immediately munmap | 212 // do a mmap with a name known by ll_prof.py and immediately munmap |
271 // it. This injects a GC marker into the stream of events generated | 213 // it. This injects a GC marker into the stream of events generated |
272 // by the kernel and allows us to synchronize V8 code log and the | 214 // by the kernel and allows us to synchronize V8 code log and the |
273 // kernel log. | 215 // kernel log. |
274 int size = sysconf(_SC_PAGESIZE); | 216 long size = sysconf(_SC_PAGESIZE); // NOLINT(runtime/int) |
275 FILE* f = fopen(OS::GetGCFakeMMapFile(), "w+"); | 217 FILE* f = fopen(OS::GetGCFakeMMapFile(), "w+"); |
276 if (f == NULL) { | 218 if (f == NULL) { |
277 OS::PrintError("Failed to open %s\n", OS::GetGCFakeMMapFile()); | 219 OS::PrintError("Failed to open %s\n", OS::GetGCFakeMMapFile()); |
278 OS::Abort(); | 220 OS::Abort(); |
279 } | 221 } |
280 void* addr = mmap(OS::GetRandomMmapAddr(), size, | 222 void* addr = mmap(OS::GetRandomMmapAddr(), size, |
281 #if V8_OS_NACL | 223 #if V8_OS_NACL |
282 // The Native Client port of V8 uses an interpreter, | 224 // The Native Client port of V8 uses an interpreter, |
283 // so code pages don't need PROT_EXEC. | 225 // so code pages don't need PROT_EXEC. |
284 PROT_READ, | 226 PROT_READ, |
285 #else | 227 #else |
286 PROT_READ | PROT_EXEC, | 228 PROT_READ | PROT_EXEC, |
287 #endif | 229 #endif |
288 MAP_PRIVATE, fileno(f), 0); | 230 MAP_PRIVATE, fileno(f), 0); |
289 DCHECK(addr != MAP_FAILED); | 231 DCHECK_NE(MAP_FAILED, addr); |
290 OS::Free(addr, size); | 232 OS::Free(addr, size); |
291 fclose(f); | 233 fclose(f); |
292 } | 234 } |
293 | 235 |
294 | 236 |
295 // Constants used for mmap. | 237 // Constants used for mmap. |
296 static const int kMmapFd = -1; | 238 static const int kMmapFd = -1; |
297 static const int kMmapFdOffset = 0; | 239 static const int kMmapFdOffset = 0; |
298 | 240 |
299 | 241 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 #endif | 379 #endif |
438 return munmap(base, size) == 0; | 380 return munmap(base, size) == 0; |
439 } | 381 } |
440 | 382 |
441 | 383 |
442 bool VirtualMemory::HasLazyCommits() { | 384 bool VirtualMemory::HasLazyCommits() { |
443 return true; | 385 return true; |
444 } | 386 } |
445 | 387 |
446 } } // namespace v8::base | 388 } } // namespace v8::base |
OLD | NEW |