Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: src/platform-linux.cc

Issue 7535004: Merge bleeding edge up to 8774 into the GC branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/platform-freebsd.cc ('k') | src/platform-macos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 71
72 72
73 double ceiling(double x) { 73 double ceiling(double x) {
74 return ceil(x); 74 return ceil(x);
75 } 75 }
76 76
77 77
78 static Mutex* limit_mutex = NULL; 78 static Mutex* limit_mutex = NULL;
79 79
80 80
81 static void* GetRandomMmapAddr() {
82 Isolate* isolate = Isolate::UncheckedCurrent();
83 // Note that the current isolate isn't set up in a call path via
84 // CpuFeatures::Probe. We don't care about randomization in this case because
85 // the code page is immediately freed.
86 if (isolate != NULL) {
87 #ifdef V8_TARGET_ARCH_X64
88 uint64_t rnd1 = V8::RandomPrivate(isolate);
89 uint64_t rnd2 = V8::RandomPrivate(isolate);
90 uint64_t raw_addr = (rnd1 << 32) ^ rnd2;
91 // Currently available CPUs have 48 bits of virtual addressing. Truncate
92 // the hint address to 46 bits to give the kernel a fighting chance of
93 // fulfilling our placement request.
94 raw_addr &= V8_UINT64_C(0x3ffffffff000);
95 #else
96 uint32_t raw_addr = V8::RandomPrivate(isolate);
97 // The range 0x20000000 - 0x60000000 is relatively unpopulated across a
98 // variety of ASLR modes (PAE kernel, NX compat mode, etc).
99 raw_addr &= 0x3ffff000;
100 raw_addr += 0x20000000;
101 #endif
102 return reinterpret_cast<void*>(raw_addr);
103 }
104 return NULL;
105 }
106
107
81 void OS::Setup() { 108 void OS::Setup() {
82 // Seed the random number generator. 109 // Seed the random number generator. We preserve microsecond resolution.
83 // Convert the current time to a 64-bit integer first, before converting it 110 uint64_t seed = Ticks() ^ (getpid() << 16);
84 // to an unsigned. Going directly can cause an overflow and the seed to be
85 // set to all ones. The seed will be identical for different instances that
86 // call this setup code within the same millisecond.
87 uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
88 srandom(static_cast<unsigned int>(seed)); 111 srandom(static_cast<unsigned int>(seed));
89 limit_mutex = CreateMutex(); 112 limit_mutex = CreateMutex();
90 113
91 #ifdef __arm__ 114 #ifdef __arm__
92 // When running on ARM hardware check that the EABI used by V8 and 115 // When running on ARM hardware check that the EABI used by V8 and
93 // by the C code is the same. 116 // by the C code is the same.
94 bool hard_float = OS::ArmUsingHardFloat(); 117 bool hard_float = OS::ArmUsingHardFloat();
95 if (hard_float) { 118 if (hard_float) {
96 #if !USE_EABI_HARDFLOAT 119 #if !USE_EABI_HARDFLOAT
97 PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without " 120 PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without "
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 383
361 384
362 size_t OS::AllocateAlignment() { 385 size_t OS::AllocateAlignment() {
363 return sysconf(_SC_PAGESIZE); 386 return sysconf(_SC_PAGESIZE);
364 } 387 }
365 388
366 389
367 void* OS::Allocate(const size_t requested, 390 void* OS::Allocate(const size_t requested,
368 size_t* allocated, 391 size_t* allocated,
369 bool is_executable) { 392 bool is_executable) {
370 // TODO(805): Port randomization of allocated executable memory to Linux.
371 const size_t msize = RoundUp(requested, AllocateAlignment()); 393 const size_t msize = RoundUp(requested, AllocateAlignment());
372 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 394 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
373 void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 395 void* addr = GetRandomMmapAddr();
396 void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
374 if (mbase == MAP_FAILED) { 397 if (mbase == MAP_FAILED) {
375 LOG(i::Isolate::Current(), 398 LOG(i::Isolate::Current(),
376 StringEvent("OS::Allocate", "mmap failed")); 399 StringEvent("OS::Allocate", "mmap failed"));
377 return NULL; 400 return NULL;
378 } 401 }
379 *allocated = msize; 402 *allocated = msize;
380 UpdateAllocatedSpaceLimits(mbase, msize); 403 UpdateAllocatedSpaceLimits(mbase, msize);
381 return mbase; 404 return mbase;
382 } 405 }
383 406
384 407
385 void OS::Free(void* address, const size_t size) { 408 void OS::Free(void* address, const size_t size) {
386 // TODO(1240712): munmap has a return value which is ignored here. 409 // TODO(1240712): munmap has a return value which is ignored here.
387 int result = munmap(address, size); 410 int result = munmap(address, size);
388 USE(result); 411 USE(result);
389 ASSERT(result == 0); 412 ASSERT(result == 0);
390 } 413 }
391 414
392 415
393 #ifdef ENABLE_HEAP_PROTECTION
394
395 void OS::Protect(void* address, size_t size) {
396 // TODO(1240712): mprotect has a return value which is ignored here.
397 mprotect(address, size, PROT_READ);
398 }
399
400
401 void OS::Unprotect(void* address, size_t size, bool is_executable) {
402 // TODO(1240712): mprotect has a return value which is ignored here.
403 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
404 mprotect(address, size, prot);
405 }
406
407 #endif
408
409
410 void OS::Sleep(int milliseconds) { 416 void OS::Sleep(int milliseconds) {
411 unsigned int ms = static_cast<unsigned int>(milliseconds); 417 unsigned int ms = static_cast<unsigned int>(milliseconds);
412 usleep(1000 * ms); 418 usleep(1000 * ms);
413 } 419 }
414 420
415 421
416 void OS::Abort() { 422 void OS::Abort() {
417 // Redirect to std abort to signal abnormal program termination. 423 // Redirect to std abort to signal abnormal program termination.
418 abort(); 424 abort();
419 } 425 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 } 482 }
477 483
478 484
479 PosixMemoryMappedFile::~PosixMemoryMappedFile() { 485 PosixMemoryMappedFile::~PosixMemoryMappedFile() {
480 if (memory_) munmap(memory_, size_); 486 if (memory_) munmap(memory_, size_);
481 fclose(file_); 487 fclose(file_);
482 } 488 }
483 489
484 490
485 void OS::LogSharedLibraryAddresses() { 491 void OS::LogSharedLibraryAddresses() {
486 #ifdef ENABLE_LOGGING_AND_PROFILING
487 // This function assumes that the layout of the file is as follows: 492 // This function assumes that the layout of the file is as follows:
488 // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name] 493 // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name]
489 // If we encounter an unexpected situation we abort scanning further entries. 494 // If we encounter an unexpected situation we abort scanning further entries.
490 FILE* fp = fopen("/proc/self/maps", "r"); 495 FILE* fp = fopen("/proc/self/maps", "r");
491 if (fp == NULL) return; 496 if (fp == NULL) return;
492 497
493 // Allocate enough room to be able to store a full file name. 498 // Allocate enough room to be able to store a full file name.
494 const int kLibNameLen = FILENAME_MAX + 1; 499 const int kLibNameLen = FILENAME_MAX + 1;
495 char* lib_name = reinterpret_cast<char*>(malloc(kLibNameLen)); 500 char* lib_name = reinterpret_cast<char*>(malloc(kLibNameLen));
496 501
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 // Entry not describing executable data. Skip to end of line to setup 538 // Entry not describing executable data. Skip to end of line to setup
534 // reading the next entry. 539 // reading the next entry.
535 do { 540 do {
536 c = getc(fp); 541 c = getc(fp);
537 } while ((c != EOF) && (c != '\n')); 542 } while ((c != EOF) && (c != '\n'));
538 if (c == EOF) break; 543 if (c == EOF) break;
539 } 544 }
540 } 545 }
541 free(lib_name); 546 free(lib_name);
542 fclose(fp); 547 fclose(fp);
543 #endif
544 } 548 }
545 549
546 550
547 static const char kGCFakeMmap[] = "/tmp/__v8_gc__"; 551 static const char kGCFakeMmap[] = "/tmp/__v8_gc__";
548 552
549 553
550 void OS::SignalCodeMovingGC() { 554 void OS::SignalCodeMovingGC() {
551 #ifdef ENABLE_LOGGING_AND_PROFILING
552 // Support for ll_prof.py. 555 // Support for ll_prof.py.
553 // 556 //
554 // The Linux profiler built into the kernel logs all mmap's with 557 // The Linux profiler built into the kernel logs all mmap's with
555 // PROT_EXEC so that analysis tools can properly attribute ticks. We 558 // PROT_EXEC so that analysis tools can properly attribute ticks. We
556 // do a mmap with a name known by ll_prof.py and immediately munmap 559 // do a mmap with a name known by ll_prof.py and immediately munmap
557 // it. This injects a GC marker into the stream of events generated 560 // it. This injects a GC marker into the stream of events generated
558 // by the kernel and allows us to synchronize V8 code log and the 561 // by the kernel and allows us to synchronize V8 code log and the
559 // kernel log. 562 // kernel log.
560 int size = sysconf(_SC_PAGESIZE); 563 int size = sysconf(_SC_PAGESIZE);
561 FILE* f = fopen(kGCFakeMmap, "w+"); 564 FILE* f = fopen(kGCFakeMmap, "w+");
562 void* addr = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_PRIVATE, 565 void* addr = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_PRIVATE,
563 fileno(f), 0); 566 fileno(f), 0);
564 ASSERT(addr != MAP_FAILED); 567 ASSERT(addr != MAP_FAILED);
565 munmap(addr, size); 568 munmap(addr, size);
566 fclose(f); 569 fclose(f);
567 #endif
568 } 570 }
569 571
570 572
571 int OS::StackWalk(Vector<OS::StackFrame> frames) { 573 int OS::StackWalk(Vector<OS::StackFrame> frames) {
572 // backtrace is a glibc extension. 574 // backtrace is a glibc extension.
573 #ifdef __GLIBC__ 575 #ifdef __GLIBC__
574 int frames_size = frames.length(); 576 int frames_size = frames.length();
575 ScopedVector<void*> addresses(frames_size); 577 ScopedVector<void*> addresses(frames_size);
576 578
577 int frames_count = backtrace(addresses.start(), frames_size); 579 int frames_count = backtrace(addresses.start(), frames_size);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 return CommitRegion(address, size, is_executable); 630 return CommitRegion(address, size, is_executable);
629 } 631 }
630 632
631 633
632 bool VirtualMemory::Uncommit(void* address, size_t size) { 634 bool VirtualMemory::Uncommit(void* address, size_t size) {
633 return UncommitRegion(address, size); 635 return UncommitRegion(address, size);
634 } 636 }
635 637
636 638
637 void* VirtualMemory::ReserveRegion(size_t size) { 639 void* VirtualMemory::ReserveRegion(size_t size) {
638 void* result = mmap(NULL, 640 void* result = mmap(GetRandomMmapAddr(),
639 size, 641 size,
640 PROT_NONE, 642 PROT_NONE,
641 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, 643 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
642 kMmapFd, 644 kMmapFd,
643 kMmapFdOffset); 645 kMmapFdOffset);
644 646
645 if (result == MAP_FAILED) return NULL; 647 if (result == MAP_FAILED) return NULL;
646 648
647 return result; 649 return result;
648 } 650 }
649 651
650 652
651 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { 653 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
652 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 654 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
653 if (MAP_FAILED == mmap(base, 655 if (MAP_FAILED == mmap(base,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 class LinuxMutex : public Mutex { 783 class LinuxMutex : public Mutex {
782 public: 784 public:
783 LinuxMutex() { 785 LinuxMutex() {
784 pthread_mutexattr_t attrs; 786 pthread_mutexattr_t attrs;
785 int result = pthread_mutexattr_init(&attrs); 787 int result = pthread_mutexattr_init(&attrs);
786 ASSERT(result == 0); 788 ASSERT(result == 0);
787 result = pthread_mutexattr_settype(&attrs, PTHREAD_MUTEX_RECURSIVE); 789 result = pthread_mutexattr_settype(&attrs, PTHREAD_MUTEX_RECURSIVE);
788 ASSERT(result == 0); 790 ASSERT(result == 0);
789 result = pthread_mutex_init(&mutex_, &attrs); 791 result = pthread_mutex_init(&mutex_, &attrs);
790 ASSERT(result == 0); 792 ASSERT(result == 0);
793 USE(result);
791 } 794 }
792 795
793 virtual ~LinuxMutex() { pthread_mutex_destroy(&mutex_); } 796 virtual ~LinuxMutex() { pthread_mutex_destroy(&mutex_); }
794 797
795 virtual int Lock() { 798 virtual int Lock() {
796 int result = pthread_mutex_lock(&mutex_); 799 int result = pthread_mutex_lock(&mutex_);
797 return result; 800 return result;
798 } 801 }
799 802
800 virtual int Unlock() { 803 virtual int Unlock() {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup. 888 CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
886 } 889 }
887 } 890 }
888 891
889 892
890 Semaphore* OS::CreateSemaphore(int count) { 893 Semaphore* OS::CreateSemaphore(int count) {
891 return new LinuxSemaphore(count); 894 return new LinuxSemaphore(count);
892 } 895 }
893 896
894 897
895 #ifdef ENABLE_LOGGING_AND_PROFILING
896
897 #if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__)) 898 #if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__))
898 // Android runs a fairly new Linux kernel, so signal info is there, 899 // Android runs a fairly new Linux kernel, so signal info is there,
899 // but the C library doesn't have the structs defined. 900 // but the C library doesn't have the structs defined.
900 901
901 struct sigcontext { 902 struct sigcontext {
902 uint32_t trap_no; 903 uint32_t trap_no;
903 uint32_t error_code; 904 uint32_t error_code;
904 uint32_t oldmask; 905 uint32_t oldmask;
905 uint32_t gregs[16]; 906 uint32_t gregs[16];
906 uint32_t arm_cpsr; 907 uint32_t arm_cpsr;
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 SignalSender::AddActiveSampler(this); 1175 SignalSender::AddActiveSampler(this);
1175 } 1176 }
1176 1177
1177 1178
1178 void Sampler::Stop() { 1179 void Sampler::Stop() {
1179 ASSERT(IsActive()); 1180 ASSERT(IsActive());
1180 SignalSender::RemoveActiveSampler(this); 1181 SignalSender::RemoveActiveSampler(this);
1181 SetActive(false); 1182 SetActive(false);
1182 } 1183 }
1183 1184
1184 #endif // ENABLE_LOGGING_AND_PROFILING
1185 1185
1186 } } // namespace v8::internal 1186 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/platform-freebsd.cc ('k') | src/platform-macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698