Skip to content

Commit e97daee

Browse files
hannespayerCommit Bot
authored andcommitted
[heap] Register executable MemoryChunks.
Bug: chromium:774108,v8:6792 Change-Id: If0ff62b959b74b7be4e00b04d7a734ab95b8ecb6 Reviewed-on: https://chromium-review.googlesource.com/867040 Reviewed-by: Michael Starzinger <[email protected]> Commit-Queue: Hannes Payer <[email protected]> Cr-Commit-Position: refs/heads/master@{#50610}
1 parent 852bdba commit e97daee

3 files changed

Lines changed: 35 additions & 2 deletions

File tree

src/heap/heap-inl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ CodeSpaceMemoryModificationScope::CodeSpaceMemoryModificationScope(Heap* heap)
624624
LargePage* page = heap_->lo_space()->first_page();
625625
while (page != nullptr) {
626626
if (page->IsFlagSet(MemoryChunk::IS_EXECUTABLE)) {
627+
CHECK(heap_->memory_allocator()->IsMemoryChunkExecutable(page));
627628
page->SetReadAndWritable();
628629
}
629630
page = page->next_page();
@@ -638,6 +639,7 @@ CodeSpaceMemoryModificationScope::~CodeSpaceMemoryModificationScope() {
638639
LargePage* page = heap_->lo_space()->first_page();
639640
while (page != nullptr) {
640641
if (page->IsFlagSet(MemoryChunk::IS_EXECUTABLE)) {
642+
CHECK(heap_->memory_allocator()->IsMemoryChunkExecutable(page));
641643
page->SetReadAndExecutable();
642644
}
643645
page = page->next_page();
@@ -654,12 +656,14 @@ CodePageMemoryModificationScope::CodePageMemoryModificationScope(
654656
DCHECK(chunk_->owner()->identity() == CODE_SPACE ||
655657
(chunk_->owner()->identity() == LO_SPACE &&
656658
chunk_->IsFlagSet(MemoryChunk::IS_EXECUTABLE)));
659+
CHECK(chunk_->heap()->memory_allocator()->IsMemoryChunkExecutable(chunk_));
657660
chunk_->SetReadAndWritable();
658661
}
659662
}
660663

661664
CodePageMemoryModificationScope::~CodePageMemoryModificationScope() {
662665
if (scope_active_) {
666+
CHECK(chunk_->heap()->memory_allocator()->IsMemoryChunkExecutable(chunk_));
663667
chunk_->SetReadAndExecutable();
664668
}
665669
}

src/heap/spaces.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -826,8 +826,13 @@ MemoryChunk* MemoryAllocator::AllocateChunk(size_t reserve_area_size,
826826
owner);
827827
}
828828

829-
return MemoryChunk::Initialize(heap, base, chunk_size, area_start, area_end,
830-
executable, owner, &reservation);
829+
MemoryChunk* chunk =
830+
MemoryChunk::Initialize(heap, base, chunk_size, area_start, area_end,
831+
executable, owner, &reservation);
832+
833+
if (executable) RegisterExecutableMemoryChunk(chunk);
834+
835+
return chunk;
831836
}
832837

833838
void Page::ResetAllocatedBytes() { allocated_bytes_ = area_size(); }
@@ -970,6 +975,8 @@ void MemoryAllocator::PreFreeMemory(MemoryChunk* chunk) {
970975
}
971976

972977
chunk->SetFlag(MemoryChunk::PRE_FREED);
978+
979+
if (chunk->executable()) UnregisterExecutableMemoryChunk(chunk);
973980
}
974981

975982

@@ -1722,13 +1729,15 @@ void PagedSpace::ReleasePage(Page* page) {
17221729
void PagedSpace::SetReadAndExecutable() {
17231730
DCHECK(identity() == CODE_SPACE);
17241731
for (Page* page : *this) {
1732+
CHECK(heap_->memory_allocator()->IsMemoryChunkExecutable(page));
17251733
page->SetReadAndExecutable();
17261734
}
17271735
}
17281736

17291737
void PagedSpace::SetReadAndWritable() {
17301738
DCHECK(identity() == CODE_SPACE);
17311739
for (Page* page : *this) {
1740+
CHECK(heap_->memory_allocator()->IsMemoryChunkExecutable(page));
17321741
page->SetReadAndWritable();
17331742
}
17341743
}

src/heap/spaces.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,6 +1359,12 @@ class V8_EXPORT_PRIVATE MemoryAllocator {
13591359
// and false otherwise.
13601360
bool CommitBlock(Address start, size_t size, Executability executable);
13611361

1362+
// Checks if an allocated MemoryChunk was intended to be used for executable
1363+
// memory.
1364+
bool IsMemoryChunkExecutable(MemoryChunk* chunk) {
1365+
return executable_memory_.find(chunk) != executable_memory_.end();
1366+
}
1367+
13621368
// Uncommit a contiguous block of memory [start..(start+size)[.
13631369
// start is not nullptr, the size is greater than zero, and the
13641370
// block is contained in the initial chunk. Returns true if it succeeded
@@ -1409,6 +1415,17 @@ class V8_EXPORT_PRIVATE MemoryAllocator {
14091415
} while ((high > ptr) && !highest_ever_allocated_.TrySetValue(ptr, high));
14101416
}
14111417

1418+
void RegisterExecutableMemoryChunk(MemoryChunk* chunk) {
1419+
DCHECK(chunk->IsFlagSet(MemoryChunk::IS_EXECUTABLE));
1420+
DCHECK_EQ(executable_memory_.find(chunk), executable_memory_.end());
1421+
executable_memory_.insert(chunk);
1422+
}
1423+
1424+
void UnregisterExecutableMemoryChunk(MemoryChunk* chunk) {
1425+
DCHECK_NE(executable_memory_.find(chunk), executable_memory_.end());
1426+
executable_memory_.erase(chunk);
1427+
}
1428+
14121429
Isolate* isolate_;
14131430
CodeRange* code_range_;
14141431

@@ -1431,6 +1448,9 @@ class V8_EXPORT_PRIVATE MemoryAllocator {
14311448
VirtualMemory last_chunk_;
14321449
Unmapper unmapper_;
14331450

1451+
// Data structure to remember allocated executable memory chunks.
1452+
std::unordered_set<MemoryChunk*> executable_memory_;
1453+
14341454
friend class heap::TestCodeRangeScope;
14351455

14361456
DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryAllocator);

0 commit comments

Comments
 (0)