heap: Add flag v8_enable_inner_pointer_resolution_osb

This CL introduces a compile flag v8_enable_inner_pointer_resolution_osb
behind which lies the experimental implementation of the object start
bitmap. It disassociates the object start bitmap from the compile flag
v8_enable_conservative_stack_scanning. At the moment the former flag is
a prerequisite for the latter, as conservative stack scanning requires
some mechanism for inner pointer resolution and the object start bitmap
provides one such mechanism.

Bug: v8:12851
Change-Id: I24c6b389453fbaefc79ae50c34c5ec7a1bf23347
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3717322
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Omer Katz <omerkatz@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Nikolaos Papaspyrou <nikolaos@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81295}
This commit is contained in:
Nikolaos Papaspyrou 2022-06-21 20:51:34 +02:00 committed by V8 LUCI CQ
parent 62ae188994
commit 852baabc17
15 changed files with 65 additions and 39 deletions

View File

@ -576,6 +576,10 @@ assert(!cppgc_enable_young_generation || cppgc_enable_caged_heap,
assert(!cppgc_enable_pointer_compression || cppgc_enable_caged_heap,
"Pointer compression in CppGC requires caged heap")
assert(!v8_enable_conservative_stack_scanning ||
v8_enable_inner_pointer_resolution_osb,
"Conservative stack scanning requires inner pointer resolution (OSB)")
if (v8_enable_single_generation == true) {
assert(
v8_enable_unconditional_write_barriers || v8_disable_write_barriers,
@ -931,6 +935,9 @@ config("features") {
if (v8_enable_conservative_stack_scanning) {
defines += [ "V8_ENABLE_CONSERVATIVE_STACK_SCANNING" ]
}
if (v8_enable_inner_pointer_resolution_osb) {
defines += [ "V8_ENABLE_INNER_POINTER_RESOLUTION_OSB" ]
}
if (v8_disable_write_barriers) {
defines += [ "V8_DISABLE_WRITE_BARRIERS" ]
}
@ -3674,8 +3681,11 @@ v8_header_set("v8_internal_headers") {
}
if (v8_enable_conservative_stack_scanning) {
sources += [ "src/heap/conservative-stack-visitor.h" ]
}
if (v8_enable_inner_pointer_resolution_osb) {
sources += [
"src/heap/conservative-stack-visitor.h",
"src/heap/object-start-bitmap-inl.h",
"src/heap/object-start-bitmap.h",
]

View File

@ -81,6 +81,9 @@ declare_args() {
# Scan the call stack conservatively during garbage collection.
v8_enable_conservative_stack_scanning = false
# Use the object start bitmap for inner pointer resolution.
v8_enable_inner_pointer_resolution_osb = false
v8_enable_google_benchmark = false
cppgc_is_standalone = false

View File

@ -477,6 +477,15 @@ DEFINE_BOOL_READONLY(conservative_stack_scanning,
V8_ENABLE_CONSERVATIVE_STACK_SCANNING_BOOL,
"use conservative stack scanning")
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
#define V8_ENABLE_INNER_POINTER_RESOLUTION_OSB_BOOL true
#else
#define V8_ENABLE_INNER_POINTER_RESOLUTION_OSB_BOOL false
#endif
DEFINE_BOOL_READONLY(inner_pointer_resolution_osb,
V8_ENABLE_INNER_POINTER_RESOLUTION_OSB_BOOL,
"use object start bitmap for IPR")
#ifdef V8_ENABLE_FUTURE
#define FUTURE_BOOL true
#else

View File

@ -15,9 +15,9 @@
#include "src/heap/read-only-spaces.h"
#include "src/heap/third-party/heap-api.h"
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
#include "src/heap/object-start-bitmap-inl.h"
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
namespace v8 {
namespace internal {
@ -148,13 +148,13 @@ V8_WARN_UNUSED_RESULT V8_INLINE AllocationResult HeapAllocator::AllocateRaw(
}
}
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
if (AllocationType::kReadOnly != type) {
DCHECK_TAG_ALIGNED(object.address());
Page::FromHeapObject(object)->object_start_bitmap()->SetBit(
object.address());
}
#endif // V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
for (auto& tracker : heap_->allocation_trackers_) {
tracker->AllocationEvent(object.address(), size_in_bytes);

View File

@ -1444,9 +1444,9 @@ void Heap::GarbageCollectionEpilogueInSafepoint(GarbageCollector collector) {
TRACE_GC(tracer(), GCTracer::Scope::HEAP_EPILOGUE_REDUCE_NEW_SPACE);
ReduceNewSpaceSize();
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
new_space()->ClearUnusedObjectStartBitmaps();
#endif // V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
}
// Ensure that unmapper task isn't running during full GC. We need access to

View File

@ -11,9 +11,9 @@
#include "src/heap/progress-bar.h"
#include "src/heap/slot-set.h"
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
#include "src/heap/object-start-bitmap.h"
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
namespace v8 {
namespace internal {
@ -71,9 +71,9 @@ class V8_EXPORT_PRIVATE MemoryChunkLayout {
FIELD(CodeObjectRegistry*, CodeObjectRegistry),
FIELD(PossiblyEmptyBuckets, PossiblyEmptyBuckets),
FIELD(ActiveSystemPages, ActiveSystemPages),
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
FIELD(ObjectStartBitmap, ObjectStartBitmap),
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
kMarkingBitmapOffset,
kMemoryChunkHeaderSize = kMarkingBitmapOffset,
kMemoryChunkHeaderStart = kSlotSetOffset,

View File

@ -130,10 +130,10 @@ MemoryChunk::MemoryChunk(Heap* heap, BaseSpace* space, size_t chunk_size,
PageSize page_size)
: BasicMemoryChunk(heap, space, chunk_size, area_start, area_end,
std::move(reservation))
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
,
object_start_bitmap_(PtrComprCageBase{heap->isolate()}, area_start)
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
{
base::AsAtomicPointer::Release_Store(&slot_set_[OLD_TO_NEW], nullptr);
base::AsAtomicPointer::Release_Store(&slot_set_[OLD_TO_OLD], nullptr);

View File

@ -215,9 +215,13 @@ class MemoryChunk : public BasicMemoryChunk {
// read-only space chunks.
void ReleaseAllocatedMemoryNeededForWritableChunk();
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
ObjectStartBitmap* object_start_bitmap() { return &object_start_bitmap_; }
#endif
const ObjectStartBitmap* object_start_bitmap() const {
return &object_start_bitmap_;
}
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
protected:
// Release all memory allocated by the chunk. Should be called when memory
@ -289,9 +293,9 @@ class MemoryChunk : public BasicMemoryChunk {
ActiveSystemPages active_system_pages_;
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
ObjectStartBitmap object_start_bitmap_;
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
private:
friend class ConcurrentMarkingState;

View File

@ -405,7 +405,7 @@ void SemiSpace::Verify() const {
CHECK_EQ(external_backing_store_bytes[t], ExternalBackingStoreBytes(t));
}
}
#endif
#endif // VERIFY_HEAP
#ifdef DEBUG
void SemiSpace::AssertValidRange(Address start, Address end) {
@ -566,11 +566,11 @@ void NewSpace::VerifyImpl(Isolate* isolate, const Page* current_page,
ExternalBackingStoreBytes(ExternalBackingStoreType::kArrayBuffer));
}
#ifdef V8_ENABLED_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
page->object_start_bitmap()->Verify();
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
}
#endif
#endif // VERIFY_HEAP
void NewSpace::PromotePageToOldSpace(Page* page) {
DCHECK(page->InYoungGeneration());
@ -783,16 +783,16 @@ void SemiSpaceNewSpace::Verify(Isolate* isolate) const {
from_space_.Verify();
to_space_.Verify();
}
#endif
#endif // VERIFY_HEAP
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
void SemiSpaceNewSpace::ClearUnusedObjectStartBitmaps() {
if (!IsFromSpaceCommitted()) return;
for (Page* page : PageRange(from_space().first_page(), nullptr)) {
page->object_start_bitmap()->Clear();
}
}
#endif // V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
bool SemiSpaceNewSpace::ShouldBePromoted(Address address) const {
Page* page = Page::FromAddress(address);

View File

@ -301,9 +301,9 @@ class NewSpace : NON_EXPORTED_BASE(public SpaceWithLinearArea) {
Address current_address) const;
#endif
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
virtual void ClearUnusedObjectStartBitmaps() = 0;
#endif // V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
virtual iterator begin() = 0;
virtual iterator end() = 0;
@ -477,9 +477,9 @@ class V8_EXPORT_PRIVATE SemiSpaceNewSpace final : public NewSpace {
void Print() override { to_space_.Print(); }
#endif
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
void ClearUnusedObjectStartBitmaps() override;
#endif // V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
Page* first_page() final { return to_space_.first_page(); }
Page* last_page() final { return to_space_.last_page(); }

View File

@ -822,9 +822,9 @@ void PagedSpaceBase::Verify(Isolate* isolate, ObjectVisitor* visitor) const {
CHECK(!page->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION));
CHECK(!page->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION));
#ifdef V8_ENABLED_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
page->object_start_bitmap()->Verify();
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
}
for (int i = 0; i < kNumTypes; i++) {
if (i == ExternalBackingStoreType::kArrayBuffer) continue;

View File

@ -14,9 +14,9 @@
#include "src/objects/objects-inl.h"
#include "src/objects/slots-inl.h"
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
#include "src/heap/object-start-bitmap-inl.h"
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
namespace v8 {
namespace internal {

View File

@ -335,9 +335,9 @@ int Sweeper::RawSweep(Page* p, FreeSpaceTreatmentMode free_space_treatment_mode,
// The free ranges map is used for filtering typed slots.
TypedSlotSet::FreeRangesMap free_ranges_map;
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
p->object_start_bitmap()->Clear();
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
// Iterate over the page using the live objects and free the memory before
// the given live object.
@ -371,9 +371,9 @@ int Sweeper::RawSweep(Page* p, FreeSpaceTreatmentMode free_space_treatment_mode,
MemoryAllocator::GetCommitPageSizeBits());
}
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
p->object_start_bitmap()->SetBit(object.address());
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
}
// If there is free memory after the last live object also free that.

View File

@ -227,7 +227,7 @@ HEAP_TEST(DoNotEvacuatePinnedPages) {
}
HEAP_TEST(ObjectStartBitmap) {
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
#ifdef V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
v8::HandleScope sc(CcTest::isolate());
@ -303,7 +303,7 @@ HEAP_TEST(ObjectStartBitmap) {
}
CHECK(page2->object_start_bitmap()->CheckBit(obj2.address()));
}
#endif
#endif // V8_ENABLE_INNER_POINTER_RESOLUTION_OSB
}
// TODO(1600): compaction of map space is temporary removed from GC.

View File

@ -517,7 +517,7 @@ v8_source_set("unittests_sources") {
sources += [ "wasm/wasm-gdbserver-unittest.cc" ]
}
if (v8_enable_conservative_stack_scanning) {
if (v8_enable_inner_pointer_resolution_osb) {
sources += [ "heap/object-start-bitmap-unittest.cc" ]
}