@@ -52,7 +52,12 @@ SafepointTable::SafepointTable(Code* code) {
5252
5353SafepointEntry SafepointTable::FindEntry (Address pc) const {
5454 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++) {
5661 // TODO(kasperl): Replace the linear search with binary search.
5762 if (GetPcOffset (i) == pc_offset) return GetEntry (i);
5863 }
@@ -137,6 +142,8 @@ unsigned SafepointTableBuilder::GetCodeOffset() const {
137142
138143
139144void SafepointTableBuilder::Emit (Assembler* assembler, int bits_per_entry) {
145+ RemoveDuplicates ();
146+
140147 // Make sure the safepoint table is properly aligned. Pad with nops.
141148 assembler->Align (kIntSize );
142149 assembler->RecordComment (" ;;; Safepoint table." );
@@ -211,6 +218,63 @@ uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info,
211218 return encoding;
212219}
213220
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+ }
214278
215279} // namespace internal
216280} // namespace v8
0 commit comments