[Memory] Add base::OS::SetPermissions method.
- Adds SetPermissions method which returns bool result. - Eliminates Guard, SetReadAndWritable, SetReadAndExecutable, and SetReadWriteAndExecutable methods. - Adds some Fuchsia memory allocation implementation. - Some minor fixes in usage of OS::AllocatePageSize and OS::CommitPageSize. - Adds DCHECKs for sanitizing parameters to OS::Allocate/Free. Bug: chromium:756050 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Change-Id: I966ec6f029dd0371d70eca20bae197d87956f8b5 Reviewed-on: https://chromium-review.googlesource.com/760657 Commit-Queue: Bill Budge <bbudge@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Cr-Commit-Position: refs/heads/master@{#49430}
This commit is contained in:
parent
19ac10e58a
commit
0df1471ac6
@ -149,9 +149,11 @@ bool VirtualMemory::Uncommit(void* address, size_t size) {
|
||||
}
|
||||
|
||||
bool VirtualMemory::Guard(void* address) {
|
||||
CHECK(InVM(address, base::OS::CommitPageSize()));
|
||||
base::OS::Guard(address, base::OS::CommitPageSize());
|
||||
return true;
|
||||
size_t page_size = base::OS::CommitPageSize();
|
||||
CHECK(InVM(address, page_size));
|
||||
bool result = base::OS::SetPermissions(address, page_size,
|
||||
base::OS::MemoryPermission::kNoAccess);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t VirtualMemory::ReleasePartial(void* free_start) {
|
||||
|
17
src/api.cc
17
src/api.cc
@ -520,16 +520,13 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
||||
virtual void SetProtection(
|
||||
void* data, size_t length,
|
||||
v8::ArrayBuffer::Allocator::Protection protection) {
|
||||
switch (protection) {
|
||||
case v8::ArrayBuffer::Allocator::Protection::kNoAccess: {
|
||||
base::OS::Guard(data, length);
|
||||
return;
|
||||
}
|
||||
case v8::ArrayBuffer::Allocator::Protection::kReadWrite: {
|
||||
base::OS::SetReadAndWritable(data, length, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
DCHECK(protection == v8::ArrayBuffer::Allocator::Protection::kNoAccess ||
|
||||
protection == v8::ArrayBuffer::Allocator::Protection::kReadWrite);
|
||||
base::OS::MemoryPermission permission =
|
||||
(protection == v8::ArrayBuffer::Allocator::Protection::kReadWrite)
|
||||
? base::OS::MemoryPermission::kReadWrite
|
||||
: base::OS::MemoryPermission::kNoAccess;
|
||||
base::OS::SetPermissions(data, length, permission);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -170,7 +170,8 @@ MemCopyUint8Function CreateMemCopyUint8Function(Isolate* isolate,
|
||||
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<MemCopyUint8Function>(buffer);
|
||||
#endif
|
||||
}
|
||||
@ -260,8 +261,8 @@ MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
|
||||
masm.GetCode(isolate, &desc);
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<MemCopyUint16Uint8Function>(buffer);
|
||||
#endif
|
||||
}
|
||||
@ -289,7 +290,8 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
|
||||
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
|
||||
#endif
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace base {
|
||||
namespace {
|
||||
|
||||
// The memory allocation implementation is taken from platform-win32.cc.
|
||||
// The mmap-based virtual memory implementation as it is used on most posix
|
||||
// The mmap-based memory allocation implementation as it is used on most posix
|
||||
// platforms does not work well because Cygwin does not support MAP_FIXED.
|
||||
// This causes OS::CommitRegion to not always commit the memory region
|
||||
// specified.
|
||||
@ -42,6 +42,8 @@ DWORD GetProtectionFromMemoryPermission(OS::MemoryPermission access) {
|
||||
return PAGE_READWRITE;
|
||||
case OS::MemoryPermission::kReadWriteExecute:
|
||||
return PAGE_EXECUTE_READWRITE;
|
||||
case OS::MemoryPermission::kReadExecute:
|
||||
return PAGE_EXECUTE_READ;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -50,8 +52,8 @@ uint8_t* RandomizedVirtualAlloc(size_t size, DWORD flags, DWORD protect,
|
||||
void* hint) {
|
||||
LPVOID base = nullptr;
|
||||
|
||||
if (protect == PAGE_EXECUTE_READWRITE || protect == PAGE_NOACCESS) {
|
||||
// For exectutable pages try and randomize the allocation address
|
||||
// For executable or reserved pages try to use the address hint.
|
||||
if (protect != PAGE_READWRITE) {
|
||||
base = VirtualAlloc(hint, size, flags, protect);
|
||||
}
|
||||
|
||||
@ -137,15 +139,26 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
|
||||
|
||||
// static
|
||||
bool OS::Free(void* address, const size_t size) {
|
||||
DCHECK_EQ(0, static_cast<uintptr_t>(address) % AllocatePageSize());
|
||||
DCHECK_EQ(0, size % AllocatePageSize());
|
||||
USE(size);
|
||||
return VirtualFree(address, 0, MEM_RELEASE) != 0;
|
||||
}
|
||||
|
||||
// static
|
||||
bool OS::CommitRegion(void* address, size_t size) {
|
||||
if (nullptr == VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE)) {
|
||||
return false;
|
||||
bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
|
||||
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
|
||||
DCHECK_EQ(0, size % CommitPageSize());
|
||||
if (access == MemoryPermission::kNoAccess) {
|
||||
return VirtualFree(address, size, MEM_DECOMMIT) != 0;
|
||||
}
|
||||
return true;
|
||||
DWORD protect = GetProtectionFromMemoryPermission(access);
|
||||
return VirtualAlloc(address, size, MEM_COMMIT, protect) != nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
bool OS::CommitRegion(void* address, size_t size) {
|
||||
return VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE) != nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -13,6 +13,25 @@
|
||||
namespace v8 {
|
||||
namespace base {
|
||||
|
||||
namespace {
|
||||
|
||||
uint32_t GetProtectionFromMemoryPermission(OS::MemoryPermission access) {
|
||||
switch (access) {
|
||||
case OS::MemoryPermission::kNoAccess:
|
||||
return 0; // no permissions
|
||||
case OS::MemoryPermission::kReadWrite:
|
||||
return ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE;
|
||||
case OS::MemoryPermission::kReadWriteExecute:
|
||||
return ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE |
|
||||
ZX_VM_FLAG_PERM_EXECUTE;
|
||||
case OS::MemoryPermission::kReadExecute:
|
||||
return ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_EXECUTE;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TimezoneCache* OS::CreateTimezoneCache() {
|
||||
return new PosixDefaultTimezoneCache();
|
||||
}
|
||||
@ -20,8 +39,6 @@ TimezoneCache* OS::CreateTimezoneCache() {
|
||||
// static
|
||||
void* OS::Allocate(void* address, size_t size, size_t alignment,
|
||||
OS::MemoryPermission access) {
|
||||
// Currently we only support reserving memory.
|
||||
DCHECK_EQ(MemoryPermission::kNoAccess, access);
|
||||
size_t page_size = OS::AllocatePageSize();
|
||||
DCHECK_EQ(0, size % page_size);
|
||||
DCHECK_EQ(0, alignment % page_size);
|
||||
@ -37,8 +54,9 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
|
||||
zx_object_set_property(vmo, ZX_PROP_NAME, kVirtualMemoryName,
|
||||
strlen(kVirtualMemoryName));
|
||||
uintptr_t reservation;
|
||||
uint32_t prot = GetProtectionFromMemoryPermission(access);
|
||||
zx_status_t status = zx_vmar_map(zx_vmar_root_self(), 0, vmo, 0, request_size,
|
||||
0 /*no permissions*/, &reservation);
|
||||
prot, &reservation);
|
||||
// Either the vmo is now referenced by the vmar, or we failed and are bailing,
|
||||
// so close the vmo either way.
|
||||
zx_handle_close(vmo);
|
||||
@ -74,16 +92,21 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
|
||||
}
|
||||
|
||||
// static
|
||||
bool OS::Free(void* address, size_t size) {
|
||||
bool OS::Free(void* address, const size_t size) {
|
||||
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % AllocatePageSize());
|
||||
DCHECK_EQ(0, size % AllocatePageSize());
|
||||
return zx_vmar_unmap(zx_vmar_root_self(),
|
||||
reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
void OS::Guard(void* address, size_t size) {
|
||||
CHECK_EQ(ZX_OK, zx_vmar_protect(zx_vmar_root_self(),
|
||||
reinterpret_cast<uintptr_t>(address), size,
|
||||
0 /*no permissions*/));
|
||||
bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
|
||||
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
|
||||
DCHECK_EQ(0, size % CommitPageSize());
|
||||
uint32_t prot = GetProtectionFromMemoryPermission(access);
|
||||
return zx_vmar_protect(zx_vmar_root_self(),
|
||||
reinterpret_cast<uintptr_t>(address), size,
|
||||
prot) == ZX_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -59,6 +59,10 @@
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
#if V8_OS_FREEBSD || V8_OS_MACOSX || V8_OS_OPENBSD || V8_OS_SOLARIS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
namespace v8 {
|
||||
namespace base {
|
||||
|
||||
@ -94,6 +98,8 @@ int GetProtectionFromMemoryPermission(OS::MemoryPermission access) {
|
||||
return PROT_READ | PROT_WRITE;
|
||||
case OS::MemoryPermission::kReadWriteExecute:
|
||||
return PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||
case OS::MemoryPermission::kReadExecute:
|
||||
return PROT_READ | PROT_EXEC;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -122,10 +128,6 @@ void* Allocate(void* address, size_t size, OS::MemoryPermission access) {
|
||||
|
||||
} // namespace
|
||||
|
||||
#if V8_OS_FREEBSD || V8_OS_MACOSX || V8_OS_OPENBSD || V8_OS_SOLARIS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
void OS::Initialize(int64_t random_seed, bool hard_abort,
|
||||
const char* const gc_fake_mmap) {
|
||||
if (random_seed) {
|
||||
@ -154,15 +156,18 @@ int OS::ActivationFrameAlignment() {
|
||||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
size_t OS::AllocatePageSize() {
|
||||
return static_cast<size_t>(sysconf(_SC_PAGESIZE));
|
||||
}
|
||||
|
||||
// static
|
||||
size_t OS::CommitPageSize() {
|
||||
static size_t page_size = getpagesize();
|
||||
return page_size;
|
||||
}
|
||||
|
||||
// static
|
||||
void* OS::GetRandomMmapAddr() {
|
||||
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
|
||||
defined(THREAD_SANITIZER)
|
||||
@ -265,54 +270,19 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
|
||||
|
||||
// static
|
||||
bool OS::Free(void* address, const size_t size) {
|
||||
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % AllocatePageSize());
|
||||
DCHECK_EQ(0, size % AllocatePageSize());
|
||||
return munmap(address, size) == 0;
|
||||
}
|
||||
#endif // !V8_OS_CYGWIN && !V8_OS_FUCHSIA
|
||||
|
||||
void OS::SetReadAndExecutable(void* address, const size_t size) {
|
||||
#if V8_OS_CYGWIN
|
||||
DWORD old_protect;
|
||||
CHECK_NOT_NULL(
|
||||
VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect));
|
||||
#else
|
||||
CHECK_EQ(0, mprotect(address, size, PROT_READ | PROT_EXEC));
|
||||
#endif
|
||||
// static
|
||||
bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
|
||||
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
|
||||
DCHECK_EQ(0, size % CommitPageSize());
|
||||
int prot = GetProtectionFromMemoryPermission(access);
|
||||
return mprotect(address, size, prot) == 0;
|
||||
}
|
||||
|
||||
// Create guard pages.
|
||||
#if !V8_OS_FUCHSIA
|
||||
void OS::Guard(void* address, const size_t size) {
|
||||
#if V8_OS_CYGWIN
|
||||
DWORD oldprotect;
|
||||
VirtualProtect(address, size, PAGE_NOACCESS, &oldprotect);
|
||||
#else
|
||||
mprotect(address, size, PROT_NONE);
|
||||
#endif
|
||||
}
|
||||
#endif // !V8_OS_FUCHSIA
|
||||
|
||||
// Make a region of memory readable and writable.
|
||||
void OS::SetReadAndWritable(void* address, const size_t size, bool commit) {
|
||||
#if V8_OS_CYGWIN
|
||||
DWORD oldprotect;
|
||||
CHECK_NOT_NULL(VirtualProtect(address, size, PAGE_READWRITE, &oldprotect));
|
||||
#else
|
||||
CHECK_EQ(0, mprotect(address, size, PROT_READ | PROT_WRITE));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Make a region of memory readable, writable, and executable.
|
||||
void OS::SetReadWriteAndExecutable(void* address, const size_t size) {
|
||||
#if V8_OS_CYGWIN
|
||||
DWORD oldprotect;
|
||||
CHECK_NOT_NULL(
|
||||
VirtualProtect(address, size, PAGE_EXECUTE_READWRITE, &oldprotect));
|
||||
#else
|
||||
CHECK_EQ(0, mprotect(address, size, PROT_READ | PROT_WRITE | PROT_EXEC));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !V8_OS_CYGWIN && !V8_OS_FUCHSIA
|
||||
// static
|
||||
bool OS::CommitRegion(void* address, size_t size) {
|
||||
#if !V8_OS_AIX
|
||||
|
@ -740,6 +740,8 @@ DWORD GetProtectionFromMemoryPermission(OS::MemoryPermission access) {
|
||||
return PAGE_READWRITE;
|
||||
case OS::MemoryPermission::kReadWriteExecute:
|
||||
return PAGE_EXECUTE_READWRITE;
|
||||
case OS::MemoryPermission::kReadExecute:
|
||||
return PAGE_EXECUTE_READ;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -757,8 +759,7 @@ uint8_t* RandomizedVirtualAlloc(size_t size, DWORD flags, DWORD protect,
|
||||
use_aslr = TRUE;
|
||||
#endif
|
||||
|
||||
if (use_aslr &&
|
||||
(protect == PAGE_EXECUTE_READWRITE || protect == PAGE_NOACCESS)) {
|
||||
if (use_aslr && protect != PAGE_READWRITE) {
|
||||
// For executable or reserved pages try to randomize the allocation address.
|
||||
base = VirtualAlloc(hint, size, flags, protect);
|
||||
}
|
||||
@ -783,10 +784,10 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
|
||||
// Add the maximum misalignment so we are guaranteed an aligned base address.
|
||||
size_t padded_size = size + (alignment - page_size);
|
||||
|
||||
int flags = (access == OS::MemoryPermission::kNoAccess)
|
||||
? MEM_RESERVE
|
||||
: MEM_RESERVE | MEM_COMMIT;
|
||||
int protect = GetProtectionFromMemoryPermission(access);
|
||||
DWORD flags = (access == OS::MemoryPermission::kNoAccess)
|
||||
? MEM_RESERVE
|
||||
: MEM_RESERVE | MEM_COMMIT;
|
||||
DWORD protect = GetProtectionFromMemoryPermission(access);
|
||||
|
||||
const int kMaxAttempts = 3;
|
||||
uint8_t* base = nullptr;
|
||||
@ -815,42 +816,27 @@ void* OS::Allocate(void* address, size_t size, size_t alignment,
|
||||
|
||||
// static
|
||||
bool OS::Free(void* address, const size_t size) {
|
||||
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % AllocatePageSize());
|
||||
// TODO(bbudge) Add DCHECK_EQ(0, size % AllocatePageSize()) when callers
|
||||
// pass the correct size on Windows.
|
||||
USE(size);
|
||||
return VirtualFree(address, 0, MEM_RELEASE) != 0;
|
||||
}
|
||||
|
||||
void OS::SetReadAndExecutable(void* address, const size_t size) {
|
||||
DWORD old_protect;
|
||||
CHECK_NE(NULL,
|
||||
VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect));
|
||||
}
|
||||
|
||||
void OS::Guard(void* address, const size_t size) {
|
||||
DWORD oldprotect;
|
||||
VirtualProtect(address, size, PAGE_NOACCESS, &oldprotect);
|
||||
}
|
||||
|
||||
void OS::SetReadAndWritable(void* address, const size_t size, bool commit) {
|
||||
if (commit) {
|
||||
CHECK(VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE));
|
||||
} else {
|
||||
DWORD oldprotect;
|
||||
CHECK_NE(NULL, VirtualProtect(address, size, PAGE_READWRITE, &oldprotect));
|
||||
// static
|
||||
bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
|
||||
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
|
||||
DCHECK_EQ(0, size % CommitPageSize());
|
||||
if (access == MemoryPermission::kNoAccess) {
|
||||
return VirtualFree(address, size, MEM_DECOMMIT) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Make a region of memory readable, writable, and executable.
|
||||
void OS::SetReadWriteAndExecutable(void* address, const size_t size) {
|
||||
DWORD oldprotect;
|
||||
CHECK_NE(NULL,
|
||||
VirtualProtect(address, size, PAGE_EXECUTE_READWRITE, &oldprotect));
|
||||
DWORD protect = GetProtectionFromMemoryPermission(access);
|
||||
return VirtualAlloc(address, size, MEM_COMMIT, protect) != nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
bool OS::CommitRegion(void* address, size_t size) {
|
||||
if (NULL == VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE) != nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -157,9 +157,13 @@ class V8_BASE_EXPORT OS {
|
||||
static PRINTF_FORMAT(1, 2) void PrintError(const char* format, ...);
|
||||
static PRINTF_FORMAT(1, 0) void VPrintError(const char* format, va_list args);
|
||||
|
||||
// Memory access permissions. Only the modes currently used by V8 are listed
|
||||
// here even though most systems support additional modes.
|
||||
enum class MemoryPermission { kNoAccess, kReadWrite, kReadWriteExecute };
|
||||
enum class MemoryPermission {
|
||||
kNoAccess,
|
||||
kReadWrite,
|
||||
// TODO(hpayer): Remove this flag. Memory should never be rwx.
|
||||
kReadWriteExecute,
|
||||
kReadExecute
|
||||
};
|
||||
|
||||
// Gets the page granularity for Allocate. Addresses returned by Allocate are
|
||||
// aligned to this size.
|
||||
@ -178,21 +182,14 @@ class V8_BASE_EXPORT OS {
|
||||
static void* Allocate(void* address, size_t size, size_t alignment,
|
||||
MemoryPermission access);
|
||||
|
||||
// Frees memory allocated by a call to Allocate.
|
||||
// Frees memory allocated by a call to Allocate. address and size must be
|
||||
// multiples of AllocatePageSize(). Returns true on success, otherwise false.
|
||||
static bool Free(void* address, const size_t size);
|
||||
|
||||
// Mark a region of memory executable and readable but not writable.
|
||||
static void SetReadAndExecutable(void* address, const size_t size);
|
||||
|
||||
// Assign memory as a guard page so that access will cause an exception.
|
||||
static void Guard(void* address, const size_t size);
|
||||
|
||||
// Make a region of memory non-executable but readable and writable.
|
||||
static void SetReadAndWritable(void* address, const size_t size, bool commit);
|
||||
|
||||
// Make a region of memory read, write, and executable. Do not use this
|
||||
// function. This is only a temporary function and will go away soon.
|
||||
static void SetReadWriteAndExecutable(void* address, const size_t size);
|
||||
// Sets permissions according to the access argument. address and size must be
|
||||
// multiples of CommitPageSize(). Returns true on success, otherwise false.
|
||||
static bool SetPermissions(void* address, size_t size,
|
||||
MemoryPermission access);
|
||||
|
||||
static bool CommitRegion(void* address, size_t size);
|
||||
|
||||
|
10
src/d8.cc
10
src/d8.cc
@ -150,12 +150,12 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase {
|
||||
#endif
|
||||
free(data);
|
||||
}
|
||||
// If {length} is at least {VM_THRESHOLD}, round up to next page size
|
||||
// and return {true}. Otherwise return {false}.
|
||||
// If {length} is at least {VM_THRESHOLD}, round up to next page size and
|
||||
// return {true}. Otherwise return {false}.
|
||||
bool RoundToPageSize(size_t* length) {
|
||||
const size_t kPageSize = base::OS::CommitPageSize();
|
||||
size_t page_size = base::OS::AllocatePageSize();
|
||||
if (*length >= VM_THRESHOLD && *length < TWO_GB) {
|
||||
*length = ((*length + kPageSize - 1) / kPageSize) * kPageSize;
|
||||
*length = RoundUp(*length, page_size);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -180,7 +180,7 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase {
|
||||
class MockArrayBufferAllocator : public ArrayBufferAllocatorBase {
|
||||
const size_t kAllocationLimit = 10 * MB;
|
||||
size_t get_actual_length(size_t length) const {
|
||||
return length > kAllocationLimit ? base::OS::CommitPageSize() : length;
|
||||
return length > kAllocationLimit ? base::OS::AllocatePageSize() : length;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -538,9 +538,11 @@ void MemoryChunk::SetReadAndExecutable() {
|
||||
if (write_unprotect_counter_ == 0) {
|
||||
Address protect_start =
|
||||
address() + MemoryAllocator::CodePageAreaStartOffset();
|
||||
DCHECK(
|
||||
IsAddressAligned(protect_start, MemoryAllocator::GetCommitPageSize()));
|
||||
base::OS::SetReadAndExecutable(protect_start, area_size());
|
||||
size_t page_size = MemoryAllocator::GetCommitPageSize();
|
||||
DCHECK(IsAddressAligned(protect_start, page_size));
|
||||
size_t protect_size = RoundUp(area_size(), page_size);
|
||||
base::OS::SetPermissions(protect_start, protect_size,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,9 +557,11 @@ void MemoryChunk::SetReadAndWritable() {
|
||||
if (write_unprotect_counter_ == 1) {
|
||||
Address unprotect_start =
|
||||
address() + MemoryAllocator::CodePageAreaStartOffset();
|
||||
DCHECK(IsAddressAligned(unprotect_start,
|
||||
MemoryAllocator::GetCommitPageSize()));
|
||||
base::OS::SetReadAndWritable(unprotect_start, area_size(), false);
|
||||
size_t page_size = MemoryAllocator::GetCommitPageSize();
|
||||
DCHECK(IsAddressAligned(unprotect_start, page_size));
|
||||
size_t unprotect_size = RoundUp(area_size(), page_size);
|
||||
base::OS::SetPermissions(unprotect_start, unprotect_size,
|
||||
base::OS::MemoryPermission::kReadWrite);
|
||||
}
|
||||
}
|
||||
|
||||
@ -571,9 +575,11 @@ void MemoryChunk::SetReadWriteAndExecutable() {
|
||||
DCHECK_LE(write_unprotect_counter_, 3);
|
||||
Address unprotect_start =
|
||||
address() + MemoryAllocator::CodePageAreaStartOffset();
|
||||
DCHECK(
|
||||
IsAddressAligned(unprotect_start, MemoryAllocator::GetCommitPageSize()));
|
||||
base::OS::SetReadWriteAndExecutable(unprotect_start, area_size());
|
||||
size_t page_size = MemoryAllocator::GetCommitPageSize();
|
||||
DCHECK(IsAddressAligned(unprotect_start, page_size));
|
||||
size_t unprotect_size = RoundUp(area_size(), page_size);
|
||||
base::OS::SetPermissions(unprotect_start, unprotect_size,
|
||||
base::OS::MemoryPermission::kReadWriteExecute);
|
||||
}
|
||||
|
||||
MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size,
|
||||
@ -621,7 +627,11 @@ MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size,
|
||||
if (FLAG_write_protect_code_memory) {
|
||||
chunk->write_unprotect_counter_ = 1;
|
||||
} else {
|
||||
base::OS::SetReadWriteAndExecutable(area_start, area_end - area_start);
|
||||
size_t page_size = MemoryAllocator::GetCommitPageSize();
|
||||
DCHECK(IsAddressAligned(area_start, page_size));
|
||||
size_t area_size = RoundUp(area_end - area_start, page_size);
|
||||
base::OS::SetPermissions(area_start, area_size,
|
||||
base::OS::MemoryPermission::kReadWriteExecute);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1137,9 +1147,7 @@ size_t MemoryAllocator::CodePageGuardStartOffset() {
|
||||
return ::RoundUp(Page::kObjectStartOffset, GetCommitPageSize());
|
||||
}
|
||||
|
||||
size_t MemoryAllocator::CodePageGuardSize() {
|
||||
return static_cast<int>(GetCommitPageSize());
|
||||
}
|
||||
size_t MemoryAllocator::CodePageGuardSize() { return GetCommitPageSize(); }
|
||||
|
||||
size_t MemoryAllocator::CodePageAreaStartOffset() {
|
||||
// We are guarding code pages: the first OS page after the header
|
||||
|
@ -39,7 +39,8 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
|
||||
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
|
||||
}
|
||||
|
||||
@ -451,7 +452,8 @@ MemMoveFunction CreateMemMoveFunction(Isolate* isolate) {
|
||||
masm.GetCode(isolate, &desc);
|
||||
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
// TODO(jkummerow): It would be nice to register this code creation event
|
||||
// with the PROFILE / GDBJIT system.
|
||||
return FUNCTION_CAST<MemMoveFunction>(buffer);
|
||||
|
@ -545,7 +545,8 @@ MemCopyUint8Function CreateMemCopyUint8Function(Isolate* isolate,
|
||||
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<MemCopyUint8Function>(buffer);
|
||||
#endif
|
||||
}
|
||||
@ -573,7 +574,8 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
|
||||
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
|
||||
#endif
|
||||
}
|
||||
|
@ -546,7 +546,8 @@ MemCopyUint8Function CreateMemCopyUint8Function(Isolate* isolate,
|
||||
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<MemCopyUint8Function>(buffer);
|
||||
#endif
|
||||
}
|
||||
@ -574,7 +575,8 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
|
||||
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
|
||||
#endif
|
||||
}
|
||||
|
@ -41,7 +41,8 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
|
||||
!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
|
||||
#endif
|
||||
}
|
||||
|
@ -38,7 +38,8 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
|
||||
!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
|
||||
#endif
|
||||
}
|
||||
|
@ -32,7 +32,8 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
|
||||
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, allocated);
|
||||
base::OS::SetReadAndExecutable(buffer, allocated);
|
||||
base::OS::SetPermissions(buffer, allocated,
|
||||
base::OS::MemoryPermission::kReadExecute);
|
||||
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ static void InitializeVM() {
|
||||
__ Ret(); \
|
||||
__ GetCode(masm.isolate(), nullptr);
|
||||
|
||||
#define TEARDOWN() v8::base::OS::Free(buf, allocated);
|
||||
#define TEARDOWN() CHECK(v8::base::OS::Free(buf, allocated));
|
||||
|
||||
#endif // ifdef USE_SIMULATOR.
|
||||
|
||||
|
@ -184,7 +184,7 @@ class MemoryAllocationPermissionsTest : public ::testing::Test {
|
||||
OS::Allocate(nullptr, page_size, page_size, permission));
|
||||
ProbeMemory(buffer, MemoryAction::kRead, can_read);
|
||||
ProbeMemory(buffer, MemoryAction::kWrite, can_write);
|
||||
OS::Free(buffer, page_size);
|
||||
CHECK(OS::Free(buffer, page_size));
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user