From 2df1620c28b79d567ef2ae5707bb80855e11bfa5 Mon Sep 17 00:00:00 2001 From: "jkummerow@chromium.org" Date: Tue, 16 Apr 2013 12:36:44 +0000 Subject: [PATCH] Make gyp work with Cygwin Review URL: https://codereview.chromium.org/13760003 Patch from Haitao Feng . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14282 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/platform-cygwin.cc | 124 ++++++++++++++++++++++++++++++++++++++---------- src/platform.h | 2 + test/cctest/test-api.cc | 16 ++----- tools/gyp/v8.gyp | 27 +++++++++-- 4 files changed, 126 insertions(+), 43 deletions(-) diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc index e13a3a6..6804af8 100644 --- a/src/platform-cygwin.cc +++ b/src/platform-cygwin.cc @@ -194,6 +194,11 @@ void OS::DebugBreak() { } +void OS::DumpBacktrace() { + // Currently unsupported. +} + + class PosixMemoryMappedFile : public OS::MemoryMappedFile { public: PosixMemoryMappedFile(FILE* file, void* memory, int size) @@ -319,6 +324,50 @@ int OS::StackWalk(Vector frames) { // This causes VirtualMemory::Commit to not always commit the memory region // specified. +static void* GetRandomAddr() { + Isolate* isolate = Isolate::UncheckedCurrent(); + // Note that the current isolate isn't set up in a call path via + // CpuFeatures::Probe. We don't care about randomization in this case because + // the code page is immediately freed. + if (isolate != NULL) { + // The address range used to randomize RWX allocations in OS::Allocate + // Try not to map pages into the default range that windows loads DLLs + // Use a multiple of 64k to prevent committing unused memory. + // Note: This does not guarantee RWX regions will be within the + // range kAllocationRandomAddressMin to kAllocationRandomAddressMax +#ifdef V8_HOST_ARCH_64_BIT + static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000; + static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000; +#else + static const intptr_t kAllocationRandomAddressMin = 0x04000000; + static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000; +#endif + uintptr_t address = (V8::RandomPrivate(isolate) << kPageSizeBits) + | kAllocationRandomAddressMin; + address &= kAllocationRandomAddressMax; + return reinterpret_cast(address); + } + return NULL; +} + + +static void* RandomizedVirtualAlloc(size_t size, int action, int protection) { + LPVOID base = NULL; + + if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) { + // For exectutable pages try and randomize the allocation address + for (size_t attempts = 0; base == NULL && attempts < 3; ++attempts) { + base = VirtualAlloc(GetRandomAddr(), size, action, protection); + } + } + + // After three attempts give up and let the OS find an address to use. + if (base == NULL) base = VirtualAlloc(NULL, size, action, protection); + + return base; +} + + VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } @@ -326,9 +375,37 @@ VirtualMemory::VirtualMemory(size_t size) : address_(ReserveRegion(size)), size_(size) { } +VirtualMemory::VirtualMemory(size_t size, size_t alignment) + : address_(NULL), size_(0) { + ASSERT(IsAligned(alignment, static_cast(OS::AllocateAlignment()))); + size_t request_size = RoundUp(size + alignment, + static_cast(OS::AllocateAlignment())); + void* address = ReserveRegion(request_size); + if (address == NULL) return; + Address base = RoundUp(static_cast
(address), alignment); + // Try reducing the size by freeing and then reallocating a specific area. + bool result = ReleaseRegion(address, request_size); + USE(result); + ASSERT(result); + address = VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS); + if (address != NULL) { + request_size = size; + ASSERT(base == static_cast
(address)); + } else { + // Resizing failed, just go with a bigger area. + address = ReserveRegion(request_size); + if (address == NULL) return; + } + address_ = address; + size_ = request_size; +} + + VirtualMemory::~VirtualMemory() { if (IsReserved()) { - if (0 == VirtualFree(address(), 0, MEM_RELEASE)) address_ = NULL; + bool result = ReleaseRegion(address_, size_); + ASSERT(result); + USE(result); } } @@ -345,19 +422,29 @@ void VirtualMemory::Reset() { bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { - int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; - if (NULL == VirtualAlloc(address, size, MEM_COMMIT, prot)) { - return false; - } - - UpdateAllocatedSpaceLimits(address, static_cast(size)); - return true; + return CommitRegion(address, size, is_executable); } bool VirtualMemory::Uncommit(void* address, size_t size) { ASSERT(IsReserved()); - return VirtualFree(address, size, MEM_DECOMMIT) != false; + return UncommitRegion(address, size); +} + + +void* VirtualMemory::ReserveRegion(size_t size) { + return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS); +} + + +bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { + int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; + if (NULL == VirtualAlloc(base, size, MEM_COMMIT, prot)) { + return false; + } + + UpdateAllocatedSpaceLimits(base, static_cast(size)); + return true; } @@ -372,26 +459,13 @@ bool VirtualMemory::Guard(void* address) { } -void* VirtualMemory::ReserveRegion(size_t size) { - return VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS); -} - - -bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { - UNIMPLEMENTED(); - return false; -} - - bool VirtualMemory::UncommitRegion(void* base, size_t size) { - UNIMPLEMENTED(); - return false; + return VirtualFree(base, size, MEM_DECOMMIT) != 0; } bool VirtualMemory::ReleaseRegion(void* base, size_t size) { - UNIMPLEMENTED(); - return false; + return VirtualFree(base, 0, MEM_RELEASE) != 0; } @@ -408,8 +482,6 @@ class Thread::PlatformData : public Malloced { }; - - Thread::Thread(const Options& options) : data_(new PlatformData()), stack_size_(options.stack_size()), diff --git a/src/platform.h b/src/platform.h index 736889c..ab75d74 100644 --- a/src/platform.h +++ b/src/platform.h @@ -91,8 +91,10 @@ inline int lrint(double flt) { #endif // _MSC_VER +#ifndef __CYGWIN__ // Random is missing on both Visual Studio and MinGW. int random(); +#endif #endif // WIN32 diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 1bd14ee..d75d5c2 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -48,14 +48,6 @@ static const bool kLogThreading = false; -static bool IsNaN(double x) { -#ifdef WIN32 - return _isnan(x); -#else - return isnan(x); -#endif -} - using ::v8::AccessorInfo; using ::v8::Arguments; using ::v8::Context; @@ -3648,7 +3640,7 @@ THREADED_TEST(ConversionException) { CheckUncle(&try_catch); double number_value = obj->NumberValue(); - CHECK_NE(0, IsNaN(number_value)); + CHECK_NE(0, isnan(number_value)); CheckUncle(&try_catch); int64_t integer_value = obj->IntegerValue(); @@ -15749,7 +15741,7 @@ static uint64_t DoubleToBits(double value) { static double DoubleToDateTime(double input) { double date_limit = 864e13; - if (IsNaN(input) || input < -date_limit || input > date_limit) { + if (isnan(input) || input < -date_limit || input > date_limit) { return i::OS::nan_value(); } return (input < 0) ? -(floor(-input)) : floor(input); @@ -15810,7 +15802,7 @@ THREADED_TEST(QuietSignalingNaNs) { // Check that Number::New preserves non-NaNs and quiets SNaNs. v8::Handle number = v8::Number::New(test_value); double stored_number = number->NumberValue(); - if (!IsNaN(test_value)) { + if (!isnan(test_value)) { CHECK_EQ(test_value, stored_number); } else { uint64_t stored_bits = DoubleToBits(stored_number); @@ -15829,7 +15821,7 @@ THREADED_TEST(QuietSignalingNaNs) { v8::Handle date = v8::Date::New(test_value); double expected_stored_date = DoubleToDateTime(test_value); double stored_date = date->NumberValue(); - if (!IsNaN(expected_stored_date)) { + if (!isnan(expected_stored_date)) { CHECK_EQ(expected_stored_date, stored_date); } else { uint64_t stored_bits = DoubleToBits(stored_date); diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp index 7233dfe..80ab63c 100644 --- a/tools/gyp/v8.gyp +++ b/tools/gyp/v8.gyp @@ -752,17 +752,34 @@ 'variables': { 'gyp_generators': '