44
55#include " src/heap/conservative-stack-visitor.h"
66
7+ #include " src/common/globals.h"
78#include " src/execution/isolate-inl.h"
9+ #include " src/heap/heap-layout.h"
810#include " src/heap/marking-inl.h"
911#include " src/heap/memory-chunk-metadata.h"
1012#include " src/heap/memory-chunk.h"
1719namespace v8 {
1820namespace internal {
1921
20- ConservativeStackVisitor::ConservativeStackVisitor (Isolate* isolate,
21- RootVisitor* delegate)
22- : ConservativeStackVisitor(isolate, delegate, delegate->collector ()) {}
23-
2422ConservativeStackVisitor::ConservativeStackVisitor (Isolate* isolate,
2523 RootVisitor* delegate,
2624 GarbageCollector collector)
@@ -40,12 +38,18 @@ ConservativeStackVisitor::ConservativeStackVisitor(Isolate* isolate,
4038#ifdef V8_COMPRESS_POINTERS
4139bool ConservativeStackVisitor::IsInterestingCage (
4240 PtrComprCageBase cage_base) const {
43- if (cage_base == cage_base_) return true ;
41+ if (cage_base == cage_base_) {
42+ return true ;
43+ }
4444#ifdef V8_EXTERNAL_CODE_SPACE
45- if (cage_base == code_cage_base_) return true ;
45+ if (cage_base == code_cage_base_) {
46+ return true ;
47+ }
4648#endif
4749#ifdef V8_ENABLE_SANDBOX
48- if (cage_base == trusted_cage_base_) return true ;
50+ if (cage_base == trusted_cage_base_) {
51+ return true ;
52+ }
4953#endif
5054 return false ;
5155}
@@ -60,9 +64,35 @@ Address ConservativeStackVisitor::FindBasePtr(
6064 // heap. Bail out if it is not.
6165 const MemoryChunk* chunk =
6266 allocator_->LookupChunkContainingAddress (maybe_inner_ptr);
63- if (chunk == nullptr ) return kNullAddress ;
67+ if (chunk == nullptr ) {
68+ return kNullAddress ;
69+ }
6470 const MemoryChunkMetadata* chunk_metadata = chunk->Metadata ();
6571 DCHECK (chunk_metadata->Contains (maybe_inner_ptr));
72+
73+ // If it is not in the young generation and we're only interested in young
74+ // generation pointers, we must ignore it.
75+ if (Heap::IsYoungGenerationCollector (collector_)) {
76+ const bool is_old = v8_flags.sticky_mark_bits
77+ ? chunk->IsFlagSet (MemoryChunk::CONTAINS_ONLY_OLD)
78+ : !chunk->InYoungGeneration ();
79+ if (is_old) return kNullAddress ;
80+
81+ // Scavenger already swapped the semi spaces, so all real objects should
82+ // be found in to space.
83+ if (collector_ == GarbageCollector::SCAVENGER ? chunk->IsToPage ()
84+ : chunk->IsFromPage ()) {
85+ return kNullAddress ;
86+ }
87+ } else {
88+ // If it is in the young generation "from" semispace, it is not used and
89+ // we must ignore it, as its markbits may not be clean.
90+ if (chunk->IsFromPage ()) {
91+ DCHECK (!v8_flags.sticky_mark_bits );
92+ return kNullAddress ;
93+ }
94+ }
95+
6696 // If it is contained in a large page, we want to mark the only object on it.
6797 if (chunk->IsLargePage ()) {
6898 // This could be simplified if we could guarantee that there are no free
@@ -71,25 +101,12 @@ Address ConservativeStackVisitor::FindBasePtr(
71101 static_cast <const LargePageMetadata*>(chunk_metadata)->GetObject ());
72102 return IsFreeSpaceOrFiller (obj, cage_base) ? kNullAddress : obj.address ();
73103 }
104+
74105 // Otherwise, we have a pointer inside a normal page.
75106 const PageMetadata* page = static_cast <const PageMetadata*>(chunk_metadata);
76- // If it is not in the young generation and we're only interested in young
77- // generation pointers, we must ignore it.
78- if (v8_flags.sticky_mark_bits ) {
79- if (Heap::IsYoungGenerationCollector (collector_) &&
80- chunk->IsFlagSet (MemoryChunk::CONTAINS_ONLY_OLD))
81- return kNullAddress ;
82- } else {
83- if (Heap::IsYoungGenerationCollector (collector_) &&
84- !chunk->InYoungGeneration ())
85- return kNullAddress ;
86-
87- // If it is in the young generation "from" semispace, it is not used and we
88- // must ignore it, as its markbits may not be clean.
89- if (chunk->IsFromPage ()) return kNullAddress ;
90- }
91-
92107 // Try to find the address of a previous valid object on this page.
108+ // TODO(379788114): Create a temporary bitmap for repeated visits to the same
109+ // page during CSS from Scavenger.
93110 Address base_ptr =
94111 MarkingBitmap::FindPreviousValidObject (page, maybe_inner_ptr);
95112 // Iterate through the objects in the page forwards, until we find the object
@@ -99,8 +116,9 @@ Address ConservativeStackVisitor::FindBasePtr(
99116 Tagged<HeapObject> obj (HeapObject::FromAddress (base_ptr));
100117 const int size = obj->Size (cage_base);
101118 DCHECK_LT (0 , size);
102- if (maybe_inner_ptr < base_ptr + size)
119+ if (maybe_inner_ptr < base_ptr + size) {
103120 return IsFreeSpaceOrFiller (obj, cage_base) ? kNullAddress : base_ptr;
121+ }
104122 base_ptr += size;
105123 DCHECK_LT (base_ptr, page->area_end ());
106124 }
@@ -135,12 +153,11 @@ void ConservativeStackVisitor::VisitConservativelyIfPointer(Address address) {
135153 if (V8HeapCompressionScheme::GetPtrComprCageBaseAddress (address) ==
136154 cage_base_.address ()) {
137155 VisitConservativelyIfPointer (address, cage_base_);
138- }
139156#ifdef V8_EXTERNAL_CODE_SPACE
140- else if (code_address_region_.contains (address)) {
157+ } else if (code_address_region_.contains (address)) {
141158 VisitConservativelyIfPointer (address, code_cage_base_);
142- }
143159#endif // V8_EXTERNAL_CODE_SPACE
160+ }
144161#else // !V8_COMPRESS_POINTERS
145162 VisitConservativelyIfPointer (address, cage_base_);
146163#endif // V8_COMPRESS_POINTERS
@@ -156,7 +173,9 @@ void ConservativeStackVisitor::VisitConservativelyIfPointer(
156173 }
157174 // Proceed with inner-pointer resolution.
158175 Address base_ptr = FindBasePtr (address, cage_base);
159- if (base_ptr == kNullAddress ) return ;
176+ if (base_ptr == kNullAddress ) {
177+ return ;
178+ }
160179 Tagged<HeapObject> obj = HeapObject::FromAddress (base_ptr);
161180 Tagged<Object> root = obj;
162181 DCHECK_NOT_NULL (delegate_);
0 commit comments