Commit 3a25d74c authored by Dominik Inführ's avatar Dominik Inführ Committed by V8 LUCI CQ

[heap] Regroup page flags to improve page flag checks

Keep page flags which are used in the write barrier together in order
to help reduce code size and reduce register usage.

Bug: v8:11708
Change-Id: I42efa1eeb431dea338d65aef0318cba479f2f431
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3811158Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82270}
parent 518de889
......@@ -17,6 +17,8 @@ namespace internal {
// Verify write barrier offsets match the the real offsets.
static_assert(BasicMemoryChunk::Flag::IS_EXECUTABLE ==
heap_internals::MemoryChunk::kIsExecutableBit);
static_assert(BasicMemoryChunk::Flag::IN_SHARED_HEAP ==
heap_internals::MemoryChunk::kInSharedHeapBit);
static_assert(BasicMemoryChunk::Flag::INCREMENTAL_MARKING ==
heap_internals::MemoryChunk::kMarkingBit);
static_assert(BasicMemoryChunk::Flag::FROM_PAGE ==
......
......@@ -31,75 +31,89 @@ class BasicMemoryChunk {
}
};
// All possible flags that can be set on a page. While the value of flags
// doesn't matter in principle, keep flags used in the write barrier together
// in order to have dense page flag checks in the write barrier.
enum Flag : uintptr_t {
NO_FLAGS = 0u,
IS_EXECUTABLE = 1u << 0,
// This page belongs to a shared heap.
IN_SHARED_HEAP = 1u << 0,
// These two flags are used in the write barrier to catch "interesting"
// references.
POINTERS_TO_HERE_ARE_INTERESTING = 1u << 1,
POINTERS_FROM_HERE_ARE_INTERESTING = 1u << 2,
// A page in the from-space or a young large page that was not scavenged
// yet.
FROM_PAGE = 1u << 3,
// A page in the to-space or a young large page that was scavenged.
TO_PAGE = 1u << 4,
LARGE_PAGE = 1u << 5,
EVACUATION_CANDIDATE = 1u << 6,
NEVER_EVACUATE = 1u << 7,
// |INCREMENTAL_MARKING|: Indicates whether incremental marking is currently
// enabled.
INCREMENTAL_MARKING = 1u << 5,
// The memory chunk belongs to the read-only heap and does not participate
// in garbage collection. This is used instead of owner for identity
// checking since read-only chunks have no owner once they are detached.
READ_ONLY_HEAP = 1u << 6,
// ----------------------------------------------------------------
// Values below here are not critical for the heap write barrier.
LARGE_PAGE = 1u << 7,
EVACUATION_CANDIDATE = 1u << 8,
NEVER_EVACUATE = 1u << 9,
// |PAGE_NEW_OLD_PROMOTION|: A page tagged with this flag has been promoted
// from new to old space during evacuation.
PAGE_NEW_OLD_PROMOTION = 1u << 9,
PAGE_NEW_OLD_PROMOTION = 1u << 10,
// |PAGE_NEW_NEW_PROMOTION|: A page tagged with this flag has been moved
// within the new space during evacuation.
PAGE_NEW_NEW_PROMOTION = 1u << 10,
PAGE_NEW_NEW_PROMOTION = 1u << 11,
// This flag is intended to be used for testing. Works only when both
// FLAG_stress_compaction and FLAG_manual_evacuation_candidates_selection
// are set. It forces the page to become an evacuation candidate at next
// candidates selection cycle.
FORCE_EVACUATION_CANDIDATE_FOR_TESTING = 1u << 11,
FORCE_EVACUATION_CANDIDATE_FOR_TESTING = 1u << 12,
// This flag is intended to be used for testing.
NEVER_ALLOCATE_ON_PAGE = 1u << 12,
NEVER_ALLOCATE_ON_PAGE = 1u << 13,
// The memory chunk is already logically freed, however the actual freeing
// still has to be performed.
PRE_FREED = 1u << 13,
PRE_FREED = 1u << 14,
// |POOLED|: When actually freeing this chunk, only uncommit and do not
// give up the reservation as we still reuse the chunk at some point.
POOLED = 1u << 14,
POOLED = 1u << 15,
// |COMPACTION_WAS_ABORTED|: Indicates that the compaction in this page
// has been aborted and needs special handling by the sweeper.
COMPACTION_WAS_ABORTED = 1u << 15,
COMPACTION_WAS_ABORTED = 1u << 16,
// |COMPACTION_WAS_ABORTED_FOR_TESTING|: During stress testing evacuation
// on pages is sometimes aborted. The flag is used to avoid repeatedly
// triggering on the same page.
COMPACTION_WAS_ABORTED_FOR_TESTING = 1u << 16,
COMPACTION_WAS_ABORTED_FOR_TESTING = 1u << 17,
// |INCREMENTAL_MARKING|: Indicates whether incremental marking is currently
// enabled.
INCREMENTAL_MARKING = 1u << 17,
NEW_SPACE_BELOW_AGE_MARK = 1u << 18,
// The memory chunk freeing bookkeeping has been performed but the chunk has
// not yet been freed.
UNREGISTERED = 1u << 19,
// The memory chunk belongs to the read-only heap and does not participate
// in garbage collection. This is used instead of owner for identity
// checking since read-only chunks have no owner once they are detached.
READ_ONLY_HEAP = 1u << 20,
// The memory chunk is pinned in memory and can't be moved. This is likely
// because there exists a potential pointer to somewhere in the chunk which
// can't be updated.
PINNED = 1u << 21,
PINNED = 1u << 20,
// This page belongs to a shared heap.
IN_SHARED_HEAP = 1u << 22,
// A Page with code objects.
IS_EXECUTABLE = 1u << 21,
};
using MainThreadFlags = base::Flags<Flag, uintptr_t>;
......
......@@ -45,12 +45,12 @@ namespace heap_internals {
struct MemoryChunk {
static constexpr uintptr_t kFlagsOffset = kSizetSize;
static constexpr uintptr_t kHeapOffset = kSizetSize + kUIntptrSize;
static constexpr uintptr_t kIsExecutableBit = uintptr_t{1} << 0;
static constexpr uintptr_t kMarkingBit = uintptr_t{1} << 17;
static constexpr uintptr_t kInSharedHeapBit = uintptr_t{1} << 0;
static constexpr uintptr_t kFromPageBit = uintptr_t{1} << 3;
static constexpr uintptr_t kToPageBit = uintptr_t{1} << 4;
static constexpr uintptr_t kReadOnlySpaceBit = uintptr_t{1} << 20;
static constexpr uintptr_t kInSharedHeapBit = uintptr_t{1} << 22;
static constexpr uintptr_t kMarkingBit = uintptr_t{1} << 5;
static constexpr uintptr_t kReadOnlySpaceBit = uintptr_t{1} << 6;
static constexpr uintptr_t kIsExecutableBit = uintptr_t{1} << 21;
V8_INLINE static heap_internals::MemoryChunk* FromHeapObject(
HeapObject object) {
......
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