• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/heap/conservative-stack-visitor.h"
6 
7 #include "src/execution/isolate-utils-inl.h"
8 #include "src/heap/large-spaces.h"
9 #include "src/heap/paged-spaces-inl.h"
10 
11 namespace v8 {
12 namespace internal {
13 
ConservativeStackVisitor(Isolate * isolate,RootVisitor * delegate)14 ConservativeStackVisitor::ConservativeStackVisitor(Isolate* isolate,
15                                                    RootVisitor* delegate)
16     : isolate_(isolate), delegate_(delegate) {}
17 
VisitPointer(const void * pointer)18 void ConservativeStackVisitor::VisitPointer(const void* pointer) {
19   VisitConservativelyIfPointer(pointer);
20 }
21 
CheckPage(Address address,MemoryChunk * page)22 bool ConservativeStackVisitor::CheckPage(Address address, MemoryChunk* page) {
23   if (address < page->area_start() || address >= page->area_end()) return false;
24 
25   auto base_ptr = page->object_start_bitmap()->FindBasePtr(address);
26   if (base_ptr == kNullAddress) {
27     return false;
28   }
29 
30   // At this point, base_ptr *must* refer to the valid object. We check if
31   // |address| resides inside the object or beyond it in unused memory.
32   HeapObject obj = HeapObject::FromAddress(base_ptr);
33   Address obj_end = obj.address() + obj.Size();
34 
35   if (address >= obj_end) {
36     // |address| points to unused memory.
37     return false;
38   }
39 
40   // TODO(jakehughes) Pinning is only required for the marking visitor. Other
41   // visitors (such as verify visitor) could work without pining. This should
42   // be moved to delegate_
43   page->SetFlag(BasicMemoryChunk::Flag::PINNED);
44 
45   Object ptr = HeapObject::FromAddress(base_ptr);
46   FullObjectSlot root = FullObjectSlot(&ptr);
47   delegate_->VisitRootPointer(Root::kHandleScope, nullptr, root);
48   DCHECK(root == FullObjectSlot(reinterpret_cast<Address>(&base_ptr)));
49   return true;
50 }
51 
VisitConservativelyIfPointer(const void * pointer)52 void ConservativeStackVisitor::VisitConservativelyIfPointer(
53     const void* pointer) {
54   auto address = reinterpret_cast<Address>(pointer);
55   if (address > isolate_->heap()->old_space()->top() ||
56       address < isolate_->heap()->old_space()->limit()) {
57     return;
58   }
59 
60   for (Page* page : *isolate_->heap()->old_space()) {
61     if (CheckPage(address, page)) {
62       return;
63     }
64   }
65 
66   for (LargePage* page : *isolate_->heap()->lo_space()) {
67     if (address >= page->area_start() && address < page->area_end()) {
68       Object ptr = page->GetObject();
69       FullObjectSlot root = FullObjectSlot(&ptr);
70       delegate_->VisitRootPointer(Root::kHandleScope, nullptr, root);
71       DCHECK(root == FullObjectSlot(&ptr));
72       return;
73     }
74   }
75 }
76 
77 }  // namespace internal
78 }  // namespace v8
79