Commit e97daee2 authored by Hannes Payer's avatar Hannes Payer Committed by Commit Bot

[heap] Register executable MemoryChunks.

Bug: chromium:774108,v8:6792
Change-Id: If0ff62b959b74b7be4e00b04d7a734ab95b8ecb6
Reviewed-on: https://chromium-review.googlesource.com/867040Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Hannes Payer <hpayer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50610}
parent 852bdba4
...@@ -624,6 +624,7 @@ CodeSpaceMemoryModificationScope::CodeSpaceMemoryModificationScope(Heap* heap) ...@@ -624,6 +624,7 @@ CodeSpaceMemoryModificationScope::CodeSpaceMemoryModificationScope(Heap* heap)
LargePage* page = heap_->lo_space()->first_page(); LargePage* page = heap_->lo_space()->first_page();
while (page != nullptr) { while (page != nullptr) {
if (page->IsFlagSet(MemoryChunk::IS_EXECUTABLE)) { if (page->IsFlagSet(MemoryChunk::IS_EXECUTABLE)) {
CHECK(heap_->memory_allocator()->IsMemoryChunkExecutable(page));
page->SetReadAndWritable(); page->SetReadAndWritable();
} }
page = page->next_page(); page = page->next_page();
...@@ -638,6 +639,7 @@ CodeSpaceMemoryModificationScope::~CodeSpaceMemoryModificationScope() { ...@@ -638,6 +639,7 @@ CodeSpaceMemoryModificationScope::~CodeSpaceMemoryModificationScope() {
LargePage* page = heap_->lo_space()->first_page(); LargePage* page = heap_->lo_space()->first_page();
while (page != nullptr) { while (page != nullptr) {
if (page->IsFlagSet(MemoryChunk::IS_EXECUTABLE)) { if (page->IsFlagSet(MemoryChunk::IS_EXECUTABLE)) {
CHECK(heap_->memory_allocator()->IsMemoryChunkExecutable(page));
page->SetReadAndExecutable(); page->SetReadAndExecutable();
} }
page = page->next_page(); page = page->next_page();
...@@ -654,12 +656,14 @@ CodePageMemoryModificationScope::CodePageMemoryModificationScope( ...@@ -654,12 +656,14 @@ CodePageMemoryModificationScope::CodePageMemoryModificationScope(
DCHECK(chunk_->owner()->identity() == CODE_SPACE || DCHECK(chunk_->owner()->identity() == CODE_SPACE ||
(chunk_->owner()->identity() == LO_SPACE && (chunk_->owner()->identity() == LO_SPACE &&
chunk_->IsFlagSet(MemoryChunk::IS_EXECUTABLE))); chunk_->IsFlagSet(MemoryChunk::IS_EXECUTABLE)));
CHECK(chunk_->heap()->memory_allocator()->IsMemoryChunkExecutable(chunk_));
chunk_->SetReadAndWritable(); chunk_->SetReadAndWritable();
} }
} }
CodePageMemoryModificationScope::~CodePageMemoryModificationScope() { CodePageMemoryModificationScope::~CodePageMemoryModificationScope() {
if (scope_active_) { if (scope_active_) {
CHECK(chunk_->heap()->memory_allocator()->IsMemoryChunkExecutable(chunk_));
chunk_->SetReadAndExecutable(); chunk_->SetReadAndExecutable();
} }
} }
......
...@@ -826,8 +826,13 @@ MemoryChunk* MemoryAllocator::AllocateChunk(size_t reserve_area_size, ...@@ -826,8 +826,13 @@ MemoryChunk* MemoryAllocator::AllocateChunk(size_t reserve_area_size,
owner); owner);
} }
return MemoryChunk::Initialize(heap, base, chunk_size, area_start, area_end, MemoryChunk* chunk =
MemoryChunk::Initialize(heap, base, chunk_size, area_start, area_end,
executable, owner, &reservation); executable, owner, &reservation);
if (executable) RegisterExecutableMemoryChunk(chunk);
return chunk;
} }
void Page::ResetAllocatedBytes() { allocated_bytes_ = area_size(); } void Page::ResetAllocatedBytes() { allocated_bytes_ = area_size(); }
...@@ -970,6 +975,8 @@ void MemoryAllocator::PreFreeMemory(MemoryChunk* chunk) { ...@@ -970,6 +975,8 @@ void MemoryAllocator::PreFreeMemory(MemoryChunk* chunk) {
} }
chunk->SetFlag(MemoryChunk::PRE_FREED); chunk->SetFlag(MemoryChunk::PRE_FREED);
if (chunk->executable()) UnregisterExecutableMemoryChunk(chunk);
} }
...@@ -1722,6 +1729,7 @@ void PagedSpace::ReleasePage(Page* page) { ...@@ -1722,6 +1729,7 @@ void PagedSpace::ReleasePage(Page* page) {
void PagedSpace::SetReadAndExecutable() { void PagedSpace::SetReadAndExecutable() {
DCHECK(identity() == CODE_SPACE); DCHECK(identity() == CODE_SPACE);
for (Page* page : *this) { for (Page* page : *this) {
CHECK(heap_->memory_allocator()->IsMemoryChunkExecutable(page));
page->SetReadAndExecutable(); page->SetReadAndExecutable();
} }
} }
...@@ -1729,6 +1737,7 @@ void PagedSpace::SetReadAndExecutable() { ...@@ -1729,6 +1737,7 @@ void PagedSpace::SetReadAndExecutable() {
void PagedSpace::SetReadAndWritable() { void PagedSpace::SetReadAndWritable() {
DCHECK(identity() == CODE_SPACE); DCHECK(identity() == CODE_SPACE);
for (Page* page : *this) { for (Page* page : *this) {
CHECK(heap_->memory_allocator()->IsMemoryChunkExecutable(page));
page->SetReadAndWritable(); page->SetReadAndWritable();
} }
} }
......
...@@ -1359,6 +1359,12 @@ class V8_EXPORT_PRIVATE MemoryAllocator { ...@@ -1359,6 +1359,12 @@ class V8_EXPORT_PRIVATE MemoryAllocator {
// and false otherwise. // and false otherwise.
bool CommitBlock(Address start, size_t size, Executability executable); bool CommitBlock(Address start, size_t size, Executability executable);
// Checks if an allocated MemoryChunk was intended to be used for executable
// memory.
bool IsMemoryChunkExecutable(MemoryChunk* chunk) {
return executable_memory_.find(chunk) != executable_memory_.end();
}
// Uncommit a contiguous block of memory [start..(start+size)[. // Uncommit a contiguous block of memory [start..(start+size)[.
// start is not nullptr, the size is greater than zero, and the // start is not nullptr, the size is greater than zero, and the
// block is contained in the initial chunk. Returns true if it succeeded // block is contained in the initial chunk. Returns true if it succeeded
...@@ -1409,6 +1415,17 @@ class V8_EXPORT_PRIVATE MemoryAllocator { ...@@ -1409,6 +1415,17 @@ class V8_EXPORT_PRIVATE MemoryAllocator {
} while ((high > ptr) && !highest_ever_allocated_.TrySetValue(ptr, high)); } while ((high > ptr) && !highest_ever_allocated_.TrySetValue(ptr, high));
} }
void RegisterExecutableMemoryChunk(MemoryChunk* chunk) {
DCHECK(chunk->IsFlagSet(MemoryChunk::IS_EXECUTABLE));
DCHECK_EQ(executable_memory_.find(chunk), executable_memory_.end());
executable_memory_.insert(chunk);
}
void UnregisterExecutableMemoryChunk(MemoryChunk* chunk) {
DCHECK_NE(executable_memory_.find(chunk), executable_memory_.end());
executable_memory_.erase(chunk);
}
Isolate* isolate_; Isolate* isolate_;
CodeRange* code_range_; CodeRange* code_range_;
...@@ -1431,6 +1448,9 @@ class V8_EXPORT_PRIVATE MemoryAllocator { ...@@ -1431,6 +1448,9 @@ class V8_EXPORT_PRIVATE MemoryAllocator {
VirtualMemory last_chunk_; VirtualMemory last_chunk_;
Unmapper unmapper_; Unmapper unmapper_;
// Data structure to remember allocated executable memory chunks.
std::unordered_set<MemoryChunk*> executable_memory_;
friend class heap::TestCodeRangeScope; friend class heap::TestCodeRangeScope;
DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryAllocator); DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryAllocator);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment