@@ -52,7 +52,12 @@ SafepointTable::SafepointTable(Code* code) {
52
52
53
53
SafepointEntry SafepointTable::FindEntry (Address pc) const {
54
54
unsigned pc_offset = static_cast <unsigned >(pc - code_->instruction_start ());
55
- for (unsigned i = 0 ; i < length (); i++) {
55
+ // We use kMaxUInt32 as sentinel value, so check that we don't hit that.
56
+ DCHECK_NE (kMaxUInt32 , pc_offset);
57
+ unsigned len = length ();
58
+ // If pc == kMaxUInt32, then this entry covers all call sites in the function.
59
+ if (len == 1 && GetPcOffset (0 ) == kMaxUInt32 ) return GetEntry (0 );
60
+ for (unsigned i = 0 ; i < len; i++) {
56
61
// TODO(kasperl): Replace the linear search with binary search.
57
62
if (GetPcOffset (i) == pc_offset) return GetEntry (i);
58
63
}
@@ -137,6 +142,8 @@ unsigned SafepointTableBuilder::GetCodeOffset() const {
137
142
138
143
139
144
void SafepointTableBuilder::Emit (Assembler* assembler, int bits_per_entry) {
145
+ RemoveDuplicates ();
146
+
140
147
// Make sure the safepoint table is properly aligned. Pad with nops.
141
148
assembler->Align (kIntSize );
142
149
assembler->RecordComment (" ;;; Safepoint table." );
@@ -211,6 +218,63 @@ uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info,
211
218
return encoding;
212
219
}
213
220
221
+ void SafepointTableBuilder::RemoveDuplicates () {
222
+ // If the table contains more than one entry, and all entries are identical
223
+ // (except for the pc), replace the whole table by a single entry with pc =
224
+ // kMaxUInt32. This especially compacts the table for wasm code without tagged
225
+ // pointers and without deoptimization info.
226
+
227
+ int length = deoptimization_info_.length ();
228
+ DCHECK_EQ (length, deopt_index_list_.length ());
229
+ DCHECK_EQ (length, indexes_.length ());
230
+ DCHECK_EQ (length, registers_.length ());
231
+
232
+ if (length < 2 ) return ;
233
+
234
+ // Check that all entries (1, length] are identical to entry 0.
235
+ for (int i = 1 ; i < length; ++i) {
236
+ if (!IsIdenticalExceptForPc (0 , i)) return ;
237
+ }
238
+
239
+ // If we get here, all entries were identical. Rewind all lists to just one
240
+ // entry, and set the pc to kMaxUInt32.
241
+ deoptimization_info_.Rewind (1 );
242
+ deopt_index_list_.Rewind (1 );
243
+ indexes_.Rewind (1 );
244
+ registers_.Rewind (1 );
245
+ deoptimization_info_[0 ].pc = kMaxUInt32 ;
246
+ }
247
+
248
+ bool SafepointTableBuilder::IsIdenticalExceptForPc (int index1,
249
+ int index2) const {
250
+ DeoptimizationInfo& deopt_info_1 = deoptimization_info_[index1];
251
+ DeoptimizationInfo& deopt_info_2 = deoptimization_info_[index2];
252
+ if (deopt_info_1.arguments != deopt_info_2.arguments ) return false ;
253
+ if (deopt_info_1.has_doubles != deopt_info_2.has_doubles ) return false ;
254
+
255
+ if (deopt_index_list_[index1] != deopt_index_list_[index2]) return false ;
256
+
257
+ ZoneList<int >* indexes1 = indexes_[index1];
258
+ ZoneList<int >* indexes2 = indexes_[index2];
259
+ if (indexes1->length () != indexes2->length ()) return false ;
260
+ for (int i = 0 ; i < indexes1->length (); ++i) {
261
+ if (indexes1->at (i) != indexes2->at (i)) return false ;
262
+ }
263
+
264
+ ZoneList<int >* registers1 = registers_[index1];
265
+ ZoneList<int >* registers2 = registers_[index2];
266
+ if (registers1) {
267
+ if (!registers2) return false ;
268
+ if (registers1->length () != registers2->length ()) return false ;
269
+ for (int i = 0 ; i < registers1->length (); ++i) {
270
+ if (registers1->at (i) != registers2->at (i)) return false ;
271
+ }
272
+ } else if (registers2) {
273
+ return false ;
274
+ }
275
+
276
+ return true ;
277
+ }
214
278
215
279
} // namespace internal
216
280
} // namespace v8
0 commit comments