@@ -68,21 +68,48 @@ class ConcurrentMarkingState final
6868// Helper class for storing in-object slot addresses and values.
6969class SlotSnapshot {
7070 public:
71- SlotSnapshot () : number_of_slots_(0 ) {}
71+ SlotSnapshot ()
72+ : number_of_object_slots_(0 ), number_of_external_pointer_slots_(0 ) {}
7273 SlotSnapshot (const SlotSnapshot&) = delete ;
7374 SlotSnapshot& operator =(const SlotSnapshot&) = delete ;
74- int number_of_slots () const { return number_of_slots_; }
75- ObjectSlot slot (int i) const { return snapshot_[i].first ; }
76- Object value (int i) const { return snapshot_[i].second ; }
77- void clear () { number_of_slots_ = 0 ; }
75+ int number_of_object_slots () const { return number_of_object_slots_; }
76+ int number_of_external_pointer_slots () const {
77+ return number_of_external_pointer_slots_;
78+ }
79+ ObjectSlot object_slot (int i) const { return object_snapshot_[i].first ; }
80+ Object object_value (int i) const { return object_snapshot_[i].second ; }
81+ ExternalPointerSlot external_pointer_slot (int i) const {
82+ return external_pointer_snapshot_[i].first ;
83+ }
84+ ExternalPointerTag external_pointer_tag (int i) const {
85+ return external_pointer_snapshot_[i].second ;
86+ }
87+ void clear () {
88+ number_of_object_slots_ = 0 ;
89+ number_of_external_pointer_slots_ = 0 ;
90+ }
7891 void add (ObjectSlot slot, Object value) {
79- snapshot_[number_of_slots_++] = {slot, value};
92+ DCHECK_LT (number_of_object_slots_, kMaxObjectSlots );
93+ object_snapshot_[number_of_object_slots_++] = {slot, value};
94+ }
95+ void add (ExternalPointerSlot slot, ExternalPointerTag tag) {
96+ DCHECK_LT (number_of_external_pointer_slots_, kMaxExternalPointerSlots );
97+ external_pointer_snapshot_[number_of_external_pointer_slots_++] = {slot,
98+ tag};
8099 }
81100
82101 private:
83- static const int kMaxSnapshotSize = JSObject::kMaxInstanceSize / kTaggedSize ;
84- int number_of_slots_;
85- std::pair<ObjectSlot, Object> snapshot_[kMaxSnapshotSize ];
102+ // Maximum number of pointer slots of objects we use snapshotting for.
103+ // ConsStrings can have 3 (Map + Left + Right) pointers.
104+ static constexpr int kMaxObjectSlots = 3 ;
105+ // Maximum number of external pointer slots of objects we use snapshotting
106+ // for. ExternalStrings can have 2 (resource + cached data) external pointers.
107+ static constexpr int kMaxExternalPointerSlots = 2 ;
108+ int number_of_object_slots_;
109+ int number_of_external_pointer_slots_;
110+ std::pair<ObjectSlot, Object> object_snapshot_[kMaxObjectSlots ];
111+ std::pair<ExternalPointerSlot, ExternalPointerTag>
112+ external_pointer_snapshot_[kMaxExternalPointerSlots ];
86113};
87114
88115class ConcurrentMarkingVisitorUtility {
@@ -114,9 +141,9 @@ class ConcurrentMarkingVisitorUtility {
114141 template <typename Visitor>
115142 static void VisitPointersInSnapshot (Visitor* visitor, HeapObject host,
116143 const SlotSnapshot& snapshot) {
117- for (int i = 0 ; i < snapshot.number_of_slots (); i++) {
118- ObjectSlot slot = snapshot.slot (i);
119- Object object = snapshot.value (i);
144+ for (int i = 0 ; i < snapshot.number_of_object_slots (); i++) {
145+ ObjectSlot slot = snapshot.object_slot (i);
146+ Object object = snapshot.object_value (i);
120147 DCHECK (!HasWeakHeapObjectTag (object));
121148 if (!object.IsHeapObject ()) continue ;
122149 HeapObject heap_object = HeapObject::cast (object);
@@ -127,6 +154,16 @@ class ConcurrentMarkingVisitorUtility {
127154 }
128155 }
129156
157+ template <typename Visitor>
158+ static void VisitExternalPointersInSnapshot (Visitor* visitor, HeapObject host,
159+ const SlotSnapshot& snapshot) {
160+ for (int i = 0 ; i < snapshot.number_of_external_pointer_slots (); i++) {
161+ ExternalPointerSlot slot = snapshot.external_pointer_slot (i);
162+ ExternalPointerTag tag = snapshot.external_pointer_tag (i);
163+ visitor->VisitExternalPointer (host, slot, tag);
164+ }
165+ }
166+
130167 template <typename Visitor, typename T>
131168 static int VisitFullyWithSnapshot (Visitor* visitor, Map map, T object) {
132169 using TBodyDescriptor = typename T::BodyDescriptor;
@@ -137,6 +174,8 @@ class ConcurrentMarkingVisitorUtility {
137174 if (!visitor->ShouldVisit (object)) return 0 ;
138175 ConcurrentMarkingVisitorUtility::VisitPointersInSnapshot (visitor, object,
139176 snapshot);
177+ ConcurrentMarkingVisitorUtility::VisitExternalPointersInSnapshot (
178+ visitor, object, snapshot);
140179 return size;
141180 }
142181
@@ -183,6 +222,11 @@ class ConcurrentMarkingVisitorUtility {
183222 UNREACHABLE ();
184223 }
185224
225+ void VisitExternalPointer (HeapObject host, ExternalPointerSlot slot,
226+ ExternalPointerTag tag) override {
227+ slot_snapshot_->add (slot, tag);
228+ }
229+
186230 void VisitCodeTarget (Code host, RelocInfo* rinfo) final {
187231 // This should never happen, because snapshotting is performed only on
188232 // some String subclasses.
@@ -453,6 +497,16 @@ class ConcurrentMarkingVisitor final
453497 return SeqTwoByteString::SizeFor (object.length (kAcquireLoad ));
454498 }
455499
500+ int VisitExternalOneByteString (Map map, ExternalOneByteString object) {
501+ return ConcurrentMarkingVisitorUtility::VisitFullyWithSnapshot (this , map,
502+ object);
503+ }
504+
505+ int VisitExternalTwoByteString (Map map, ExternalTwoByteString object) {
506+ return ConcurrentMarkingVisitorUtility::VisitFullyWithSnapshot (this , map,
507+ object);
508+ }
509+
456510 // Implements ephemeron semantics: Marks value if key is already reachable.
457511 // Returns true if value was actually marked.
458512 bool ProcessEphemeron (HeapObject key, HeapObject value) {
0 commit comments