@@ -65,21 +65,48 @@ class ConcurrentMarkingState final
65
65
// Helper class for storing in-object slot addresses and values.
66
66
class SlotSnapshot {
67
67
public:
68
- SlotSnapshot () : number_of_slots_(0 ) {}
68
+ SlotSnapshot ()
69
+ : number_of_object_slots_(0 ), number_of_external_pointer_slots_(0 ) {}
69
70
SlotSnapshot (const SlotSnapshot&) = delete ;
70
71
SlotSnapshot& operator =(const SlotSnapshot&) = delete ;
71
- int number_of_slots () const { return number_of_slots_; }
72
- ObjectSlot slot (int i) const { return snapshot_[i].first ; }
73
- Object value (int i) const { return snapshot_[i].second ; }
74
- void clear () { number_of_slots_ = 0 ; }
72
+ int number_of_object_slots () const { return number_of_object_slots_; }
73
+ int number_of_external_pointer_slots () const {
74
+ return number_of_external_pointer_slots_;
75
+ }
76
+ ObjectSlot object_slot (int i) const { return object_snapshot_[i].first ; }
77
+ Object object_value (int i) const { return object_snapshot_[i].second ; }
78
+ ExternalPointerSlot external_pointer_slot (int i) const {
79
+ return external_pointer_snapshot_[i].first ;
80
+ }
81
+ ExternalPointerTag external_pointer_tag (int i) const {
82
+ return external_pointer_snapshot_[i].second ;
83
+ }
84
+ void clear () {
85
+ number_of_object_slots_ = 0 ;
86
+ number_of_external_pointer_slots_ = 0 ;
87
+ }
75
88
void add (ObjectSlot slot, Object value) {
76
- snapshot_[number_of_slots_++] = {slot, value};
89
+ DCHECK_LT (number_of_object_slots_, kMaxObjectSlots );
90
+ object_snapshot_[number_of_object_slots_++] = {slot, value};
91
+ }
92
+ void add (ExternalPointerSlot slot, ExternalPointerTag tag) {
93
+ DCHECK_LT (number_of_external_pointer_slots_, kMaxExternalPointerSlots );
94
+ external_pointer_snapshot_[number_of_external_pointer_slots_++] = {slot,
95
+ tag};
77
96
}
78
97
79
98
private:
80
- static const int kMaxSnapshotSize = JSObject::kMaxInstanceSize / kTaggedSize ;
81
- int number_of_slots_;
82
- std::pair<ObjectSlot, Object> snapshot_[kMaxSnapshotSize ];
99
+ // Maximum number of pointer slots of objects we use snapshotting for.
100
+ // ConsStrings can have 3 (Map + Left + Right) pointers.
101
+ static constexpr int kMaxObjectSlots = 3 ;
102
+ // Maximum number of external pointer slots of objects we use snapshotting
103
+ // for. ExternalStrings can have 2 (resource + cached data) external pointers.
104
+ static constexpr int kMaxExternalPointerSlots = 2 ;
105
+ int number_of_object_slots_;
106
+ int number_of_external_pointer_slots_;
107
+ std::pair<ObjectSlot, Object> object_snapshot_[kMaxObjectSlots ];
108
+ std::pair<ExternalPointerSlot, ExternalPointerTag>
109
+ external_pointer_snapshot_[kMaxExternalPointerSlots ];
83
110
};
84
111
85
112
class ConcurrentMarkingVisitorUtility {
@@ -111,9 +138,9 @@ class ConcurrentMarkingVisitorUtility {
111
138
template <typename Visitor>
112
139
static void VisitPointersInSnapshot (Visitor* visitor, HeapObject host,
113
140
const SlotSnapshot& snapshot) {
114
- for (int i = 0 ; i < snapshot.number_of_slots (); i++) {
115
- ObjectSlot slot = snapshot.slot (i);
116
- Object object = snapshot.value (i);
141
+ for (int i = 0 ; i < snapshot.number_of_object_slots (); i++) {
142
+ ObjectSlot slot = snapshot.object_slot (i);
143
+ Object object = snapshot.object_value (i);
117
144
DCHECK (!HasWeakHeapObjectTag (object));
118
145
if (!object.IsHeapObject ()) continue ;
119
146
HeapObject heap_object = HeapObject::cast (object);
@@ -126,6 +153,16 @@ class ConcurrentMarkingVisitorUtility {
126
153
}
127
154
}
128
155
156
+ template <typename Visitor>
157
+ static void VisitExternalPointersInSnapshot (Visitor* visitor, HeapObject host,
158
+ const SlotSnapshot& snapshot) {
159
+ for (int i = 0 ; i < snapshot.number_of_external_pointer_slots (); i++) {
160
+ ExternalPointerSlot slot = snapshot.external_pointer_slot (i);
161
+ ExternalPointerTag tag = snapshot.external_pointer_tag (i);
162
+ visitor->VisitExternalPointer (host, slot, tag);
163
+ }
164
+ }
165
+
129
166
template <typename Visitor, typename T>
130
167
static int VisitFullyWithSnapshot (Visitor* visitor, Map map, T object) {
131
168
using TBodyDescriptor = typename T::BodyDescriptor;
@@ -136,6 +173,8 @@ class ConcurrentMarkingVisitorUtility {
136
173
if (!visitor->ShouldVisit (object)) return 0 ;
137
174
ConcurrentMarkingVisitorUtility::VisitPointersInSnapshot (visitor, object,
138
175
snapshot);
176
+ ConcurrentMarkingVisitorUtility::VisitExternalPointersInSnapshot (
177
+ visitor, object, snapshot);
139
178
return size;
140
179
}
141
180
@@ -182,6 +221,11 @@ class ConcurrentMarkingVisitorUtility {
182
221
UNREACHABLE ();
183
222
}
184
223
224
+ void VisitExternalPointer (HeapObject host, ExternalPointerSlot slot,
225
+ ExternalPointerTag tag) override {
226
+ slot_snapshot_->add (slot, tag);
227
+ }
228
+
185
229
void VisitCodeTarget (Code host, RelocInfo* rinfo) final {
186
230
// This should never happen, because snapshotting is performed only on
187
231
// some String subclasses.
@@ -450,6 +494,16 @@ class ConcurrentMarkingVisitor final
450
494
return SeqTwoByteString::SizeFor (object.length (kAcquireLoad ));
451
495
}
452
496
497
+ int VisitExternalOneByteString (Map map, ExternalOneByteString object) {
498
+ return ConcurrentMarkingVisitorUtility::VisitFullyWithSnapshot (this , map,
499
+ object);
500
+ }
501
+
502
+ int VisitExternalTwoByteString (Map map, ExternalTwoByteString object) {
503
+ return ConcurrentMarkingVisitorUtility::VisitFullyWithSnapshot (this , map,
504
+ object);
505
+ }
506
+
453
507
// Implements ephemeron semantics: Marks value if key is already reachable.
454
508
// Returns true if value was actually marked.
455
509
bool ProcessEphemeron (HeapObject key, HeapObject value) {
0 commit comments