| 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 |