105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 43a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 5e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org// Platform-specific code for Cygwin goes here. For the POSIX-compatible 6e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org// parts, the implementation is in platform-posix.cc. 73a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 83a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org#include <errno.h> 93a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org#include <pthread.h> 103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org#include <semaphore.h> 113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org#include <stdarg.h> 123a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org#include <strings.h> // index 133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org#include <sys/mman.h> // mmap & munmap 144b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <sys/time.h> 153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org#include <unistd.h> // sysconf 163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 17248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#include <cmath> 183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 19248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#undef MAP_TYPE 203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 215de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/macros.h" 225de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/platform.h" 231e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#include "src/base/win32-headers.h" 243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgnamespace v8 { 265de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgnamespace base { 273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 296b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgconst char* OS::LocalTimezone(double time, TimezoneCache* cache) { 3077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (std::isnan(time)) return ""; 31e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); 323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org struct tm* t = localtime(&tv); 333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (NULL == t) return ""; 343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return tzname[0]; // The location of the timezone string on Cygwin. 353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 386b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgdouble OS::LocalTimeOffset(TimezoneCache* cache) { 393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // On Cygwin, struct tm does not contain a tm_gmtoff field. 403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org time_t utc = time(NULL); 41e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(utc != -1); 423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org struct tm* loc = localtime(&utc); 43e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(loc != NULL); 443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // time - localtime includes any daylight savings offset, so subtract it. 453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return static_cast<double>((mktime(loc) - utc) * msPerSecond - 463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org (loc->tm_isdst > 0 ? 3600 * msPerSecond : 0)); 473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid* OS::Allocate(const size_t requested, 513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org size_t* allocated, 523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org bool is_executable) { 533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org const size_t msize = RoundUp(requested, sysconf(_SC_PAGESIZE)); 543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 561845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (mbase == MAP_FAILED) return NULL; 573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org *allocated = msize; 583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return mbase; 593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgclass PosixMemoryMappedFile : public OS::MemoryMappedFile { 633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public: 643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org PosixMemoryMappedFile(FILE* file, void* memory, int size) 653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org : file_(file), memory_(memory), size_(size) { } 663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org virtual ~PosixMemoryMappedFile(); 673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org virtual void* memory() { return memory_; } 683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org virtual int size() { return size_; } 693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private: 703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org FILE* file_; 713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void* memory_; 723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int size_; 733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}; 743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { 773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org FILE* file = fopen(name, "r+"); 783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (file == NULL) return NULL; 793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org fseek(file, 0, SEEK_END); 813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int size = ftell(file); 823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void* memory = 843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0); 853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return new PosixMemoryMappedFile(file, memory, size); 863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, 903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void* initial) { 913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org FILE* file = fopen(name, "w+"); 923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (file == NULL) return NULL; 933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int result = fwrite(initial, size, 1, file); 943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (result < 1) { 953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org fclose(file); 963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return NULL; 973a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void* memory = 993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0); 1003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return new PosixMemoryMappedFile(file, memory, size); 1013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 1023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgPosixMemoryMappedFile::~PosixMemoryMappedFile() { 1053a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (memory_) munmap(memory_, size_); 1063a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org fclose(file_); 1073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 1083a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1093a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1101845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgstd::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() { 1111845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org std::vector<SharedLibraryAddresses> result; 1123a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // This function assumes that the layout of the file is as follows: 1133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name] 1143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // If we encounter an unexpected situation we abort scanning further entries. 1153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org FILE* fp = fopen("/proc/self/maps", "r"); 1161845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (fp == NULL) return result; 1173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Allocate enough room to be able to store a full file name. 1193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org const int kLibNameLen = FILENAME_MAX + 1; 1203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org char* lib_name = reinterpret_cast<char*>(malloc(kLibNameLen)); 1213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // This loop will terminate once the scanning hits an EOF. 1233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org while (true) { 1243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org uintptr_t start, end; 1253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org char attr_r, attr_w, attr_x, attr_p; 1263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Parse the addresses and permission bits at the beginning of the line. 1273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (fscanf(fp, "%" V8PRIxPTR "-%" V8PRIxPTR, &start, &end) != 2) break; 1283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (fscanf(fp, " %c%c%c%c", &attr_r, &attr_w, &attr_x, &attr_p) != 4) break; 1293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int c; 1313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (attr_r == 'r' && attr_w != 'w' && attr_x == 'x') { 1323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Found a read-only executable entry. Skip characters until we reach 1333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // the beginning of the filename or the end of the line. 1343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org do { 1353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org c = getc(fp); 1363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } while ((c != EOF) && (c != '\n') && (c != '/')); 1373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (c == EOF) break; // EOF: Was unexpected, just exit. 1383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Process the filename if found. 1403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (c == '/') { 1413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ungetc(c, fp); // Push the '/' back into the stream to be read below. 1423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Read to the end of the line. Exit if the read fails. 1443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (fgets(lib_name, kLibNameLen, fp) == NULL) break; 1453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Drop the newline character read by fgets. We do not need to check 1473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // for a zero-length string because we know that we at least read the 1483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // '/' character. 1493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org lib_name[strlen(lib_name) - 1] = '\0'; 1503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 1513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // No library name found, just record the raw address range. 1523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org snprintf(lib_name, kLibNameLen, 1533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org "%08" V8PRIxPTR "-%08" V8PRIxPTR, start, end); 1543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 1551845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org result.push_back(SharedLibraryAddress(lib_name, start, end)); 1563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 157f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Entry not describing executable data. Skip to end of line to set up 1583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // reading the next entry. 1593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org do { 1603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org c = getc(fp); 1613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } while ((c != EOF) && (c != '\n')); 1623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (c == EOF) break; 1633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 1643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 1653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org free(lib_name); 1663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org fclose(fp); 1671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return result; 1683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 1693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid OS::SignalCodeMovingGC() { 1723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Nothing to do on Cygwin. 1733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 1743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 176c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// The VirtualMemory implementation is taken from platform-win32.cc. 177c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// The mmap-based virtual memory implementation as it is used on most posix 178c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// platforms does not work well because Cygwin does not support MAP_FIXED. 179c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// This causes VirtualMemory::Commit to not always commit the memory region 180c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// specified. 181c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 182e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstatic void* RandomizedVirtualAlloc(size_t size, int action, int protection) { 183e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org LPVOID base = NULL; 184e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 185e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) { 186e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // For exectutable pages try and randomize the allocation address 187e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org for (size_t attempts = 0; base == NULL && attempts < 3; ++attempts) { 188d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org base = VirtualAlloc(OS::GetRandomMmapAddr(), size, action, protection); 189e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 190e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 191e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 192e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // After three attempts give up and let the OS find an address to use. 193e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (base == NULL) base = VirtualAlloc(NULL, size, action, protection); 194e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 195e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return base; 196c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org} 1973a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 199e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } 200e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 201e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 202e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgVirtualMemory::VirtualMemory(size_t size) 203e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org : address_(ReserveRegion(size)), size_(size) { } 204e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 205e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 206e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgVirtualMemory::VirtualMemory(size_t size, size_t alignment) 207e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org : address_(NULL), size_(0) { 208e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org DCHECK((alignment % OS::AllocateAlignment()) == 0); 209e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org size_t request_size = RoundUp(size + alignment, 210e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static_cast<intptr_t>(OS::AllocateAlignment())); 211e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void* address = ReserveRegion(request_size); 212e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (address == NULL) return; 213248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org uint8_t* base = RoundUp(static_cast<uint8_t*>(address), alignment); 214e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Try reducing the size by freeing and then reallocating a specific area. 215e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool result = ReleaseRegion(address, request_size); 216e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org USE(result); 217e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result); 218e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org address = VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS); 219e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (address != NULL) { 220e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org request_size = size; 221e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(base == static_cast<uint8_t*>(address)); 222e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 223e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Resizing failed, just go with a bigger area. 224e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org address = ReserveRegion(request_size); 225e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (address == NULL) return; 226e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 227e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org address_ = address; 228e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org size_ = request_size; 2293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 2303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgVirtualMemory::~VirtualMemory() { 2333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (IsReserved()) { 234e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool result = ReleaseRegion(address_, size_); 235e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result); 236e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org USE(result); 2373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 2383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 2393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 241e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::IsReserved() { 242e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return address_ != NULL; 243e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 2443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 245e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 246e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid VirtualMemory::Reset() { 247e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org address_ = NULL; 248e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org size_ = 0; 249e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 250e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 251e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 252e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { 253e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return CommitRegion(address, size, is_executable); 2543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 2553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgbool VirtualMemory::Uncommit(void* address, size_t size) { 258e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsReserved()); 259e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return UncommitRegion(address, size); 260e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 261e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 262e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 263e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid* VirtualMemory::ReserveRegion(size_t size) { 264e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS); 265e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 266e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 267e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 268e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { 269e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; 270e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (NULL == VirtualAlloc(base, size, MEM_COMMIT, prot)) { 271e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return false; 272e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 273e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return true; 2743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 2753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 277ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.orgbool VirtualMemory::Guard(void* address) { 278ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org if (NULL == VirtualAlloc(address, 279ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org OS::CommitPageSize(), 280ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org MEM_COMMIT, 281c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org PAGE_NOACCESS)) { 282ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org return false; 283ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org } 284ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org return true; 285ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org} 286ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 287ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 288e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::UncommitRegion(void* base, size_t size) { 289e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return VirtualFree(base, size, MEM_DECOMMIT) != 0; 290e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 291e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 292e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 293e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::ReleaseRegion(void* base, size_t size) { 294e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return VirtualFree(base, 0, MEM_RELEASE) != 0; 295e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 296e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 297e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 29872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgbool VirtualMemory::HasLazyCommits() { 29972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // TODO(alph): implement for the platform. 30072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org return false; 30172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org} 30272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 3035de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org} } // namespace v8::base 304