Refactor SafepointTableBuilder to only store one ZoneList
Instead of holding four ZoneLists, which always have the same length anyway, just store all information in one struct, being held in one ZoneList. There is probably more optimization potential in the generation and encoding of safepoint tables; this is a first step to reduce its overhead. R=mstarzinger@chromium.org Bug: v8:7109 Change-Id: Ib4f752958c8d5713b46324e76003cd815e5ffd2d Reviewed-on: https://chromium-review.googlesource.com/817197 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#50006}
This commit is contained in:
parent
94523395c5
commit
b846c7a612
@ -132,28 +132,20 @@ Safepoint SafepointTableBuilder::DefineSafepoint(
|
||||
int arguments,
|
||||
Safepoint::DeoptMode deopt_mode) {
|
||||
DCHECK_GE(arguments, 0);
|
||||
DeoptimizationInfo info;
|
||||
info.pc = assembler->pc_offset();
|
||||
info.arguments = arguments;
|
||||
info.has_doubles = (kind & Safepoint::kWithDoubles);
|
||||
info.trampoline = -1;
|
||||
deoptimization_info_.Add(info, zone_);
|
||||
deopt_index_list_.Add(Safepoint::kNoDeoptimizationIndex, zone_);
|
||||
deoptimization_info_.Add(
|
||||
DeoptimizationInfo(zone_, assembler->pc_offset(), arguments, kind),
|
||||
zone_);
|
||||
if (deopt_mode == Safepoint::kNoLazyDeopt) {
|
||||
last_lazy_safepoint_ = deopt_index_list_.length();
|
||||
last_lazy_safepoint_ = deoptimization_info_.length();
|
||||
}
|
||||
indexes_.Add(new(zone_) ZoneList<int>(8, zone_), zone_);
|
||||
registers_.Add((kind & Safepoint::kWithRegisters)
|
||||
? new (zone_) ZoneList<int>(4, zone_)
|
||||
: nullptr,
|
||||
zone_);
|
||||
return Safepoint(indexes_.last(), registers_.last());
|
||||
DeoptimizationInfo& new_info = deoptimization_info_.last();
|
||||
return Safepoint(new_info.indexes, new_info.registers);
|
||||
}
|
||||
|
||||
|
||||
void SafepointTableBuilder::RecordLazyDeoptimizationIndex(int index) {
|
||||
while (last_lazy_safepoint_ < deopt_index_list_.length()) {
|
||||
deopt_index_list_[last_lazy_safepoint_++] = index;
|
||||
while (last_lazy_safepoint_ < deoptimization_info_.length()) {
|
||||
deoptimization_info_[last_lazy_safepoint_++].deopt_index = index;
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,17 +191,17 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) {
|
||||
|
||||
// Emit sorted table of pc offsets together with deoptimization indexes.
|
||||
for (int i = 0; i < length; i++) {
|
||||
assembler->dd(deoptimization_info_[i].pc);
|
||||
assembler->dd(EncodeExceptPC(deoptimization_info_[i],
|
||||
deopt_index_list_[i]));
|
||||
assembler->dd(deoptimization_info_[i].trampoline);
|
||||
const DeoptimizationInfo& info = deoptimization_info_[i];
|
||||
assembler->dd(info.pc);
|
||||
assembler->dd(EncodeExceptPC(info));
|
||||
assembler->dd(info.trampoline);
|
||||
}
|
||||
|
||||
// Emit table of bitmaps.
|
||||
ZoneList<uint8_t> bits(bytes_per_entry, zone_);
|
||||
for (int i = 0; i < length; i++) {
|
||||
ZoneList<int>* indexes = indexes_[i];
|
||||
ZoneList<int>* registers = registers_[i];
|
||||
ZoneList<int>* indexes = deoptimization_info_[i].indexes;
|
||||
ZoneList<int>* registers = deoptimization_info_[i].registers;
|
||||
bits.Clear();
|
||||
bits.AddBlock(0, bytes_per_entry, zone_);
|
||||
|
||||
@ -246,13 +238,10 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) {
|
||||
emitted_ = true;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info,
|
||||
unsigned index) {
|
||||
uint32_t encoding = SafepointEntry::DeoptimizationIndexField::encode(index);
|
||||
encoding |= SafepointEntry::ArgumentsField::encode(info.arguments);
|
||||
encoding |= SafepointEntry::SaveDoublesField::encode(info.has_doubles);
|
||||
return encoding;
|
||||
uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info) {
|
||||
return SafepointEntry::DeoptimizationIndexField::encode(info.deopt_index) |
|
||||
SafepointEntry::ArgumentsField::encode(info.arguments) |
|
||||
SafepointEntry::SaveDoublesField::encode(info.has_doubles);
|
||||
}
|
||||
|
||||
void SafepointTableBuilder::RemoveDuplicates() {
|
||||
@ -262,44 +251,36 @@ void SafepointTableBuilder::RemoveDuplicates() {
|
||||
// pointers and without deoptimization info.
|
||||
|
||||
int length = deoptimization_info_.length();
|
||||
DCHECK_EQ(length, deopt_index_list_.length());
|
||||
DCHECK_EQ(length, indexes_.length());
|
||||
DCHECK_EQ(length, registers_.length());
|
||||
|
||||
if (length < 2) return;
|
||||
|
||||
// Check that all entries (1, length] are identical to entry 0.
|
||||
const DeoptimizationInfo& first_info = deoptimization_info_[0];
|
||||
for (int i = 1; i < length; ++i) {
|
||||
if (!IsIdenticalExceptForPc(0, i)) return;
|
||||
if (!IsIdenticalExceptForPc(first_info, deoptimization_info_[i])) return;
|
||||
}
|
||||
|
||||
// If we get here, all entries were identical. Rewind all lists to just one
|
||||
// If we get here, all entries were identical. Rewind the list to just one
|
||||
// entry, and set the pc to kMaxUInt32.
|
||||
deoptimization_info_.Rewind(1);
|
||||
deopt_index_list_.Rewind(1);
|
||||
indexes_.Rewind(1);
|
||||
registers_.Rewind(1);
|
||||
deoptimization_info_[0].pc = kMaxUInt32;
|
||||
}
|
||||
|
||||
bool SafepointTableBuilder::IsIdenticalExceptForPc(int index1,
|
||||
int index2) const {
|
||||
DeoptimizationInfo& deopt_info_1 = deoptimization_info_[index1];
|
||||
DeoptimizationInfo& deopt_info_2 = deoptimization_info_[index2];
|
||||
if (deopt_info_1.arguments != deopt_info_2.arguments) return false;
|
||||
if (deopt_info_1.has_doubles != deopt_info_2.has_doubles) return false;
|
||||
bool SafepointTableBuilder::IsIdenticalExceptForPc(
|
||||
const DeoptimizationInfo& info1, const DeoptimizationInfo& info2) const {
|
||||
if (info1.arguments != info2.arguments) return false;
|
||||
if (info1.has_doubles != info2.has_doubles) return false;
|
||||
|
||||
if (deopt_index_list_[index1] != deopt_index_list_[index2]) return false;
|
||||
if (info1.deopt_index != info2.deopt_index) return false;
|
||||
|
||||
ZoneList<int>* indexes1 = indexes_[index1];
|
||||
ZoneList<int>* indexes2 = indexes_[index2];
|
||||
ZoneList<int>* indexes1 = info1.indexes;
|
||||
ZoneList<int>* indexes2 = info2.indexes;
|
||||
if (indexes1->length() != indexes2->length()) return false;
|
||||
for (int i = 0; i < indexes1->length(); ++i) {
|
||||
if (indexes1->at(i) != indexes2->at(i)) return false;
|
||||
}
|
||||
|
||||
ZoneList<int>* registers1 = registers_[index1];
|
||||
ZoneList<int>* registers2 = registers_[index2];
|
||||
ZoneList<int>* registers1 = info1.registers;
|
||||
ZoneList<int>* registers2 = info2.registers;
|
||||
if (registers1) {
|
||||
if (!registers2) return false;
|
||||
if (registers1->length() != registers2->length()) return false;
|
||||
|
@ -194,8 +194,8 @@ class Safepoint BASE_EMBEDDED {
|
||||
private:
|
||||
Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers)
|
||||
: indexes_(indexes), registers_(registers) {}
|
||||
ZoneList<int>* indexes_;
|
||||
ZoneList<int>* registers_;
|
||||
ZoneList<int>* const indexes_;
|
||||
ZoneList<int>* const registers_;
|
||||
|
||||
friend class SafepointTableBuilder;
|
||||
};
|
||||
@ -205,9 +205,6 @@ class SafepointTableBuilder BASE_EMBEDDED {
|
||||
public:
|
||||
explicit SafepointTableBuilder(Zone* zone)
|
||||
: deoptimization_info_(32, zone),
|
||||
deopt_index_list_(32, zone),
|
||||
indexes_(32, zone),
|
||||
registers_(32, zone),
|
||||
emitted_(false),
|
||||
last_lazy_safepoint_(0),
|
||||
zone_(zone) { }
|
||||
@ -225,7 +222,7 @@ class SafepointTableBuilder BASE_EMBEDDED {
|
||||
// outstanding safepoints.
|
||||
void RecordLazyDeoptimizationIndex(int index);
|
||||
void BumpLastLazySafepointIndex() {
|
||||
last_lazy_safepoint_ = deopt_index_list_.length();
|
||||
last_lazy_safepoint_ = deoptimization_info_.length();
|
||||
}
|
||||
|
||||
// Emit the safepoint table after the body. The number of bits per
|
||||
@ -244,18 +241,30 @@ class SafepointTableBuilder BASE_EMBEDDED {
|
||||
unsigned arguments;
|
||||
bool has_doubles;
|
||||
int trampoline;
|
||||
ZoneList<int>* indexes;
|
||||
ZoneList<int>* registers;
|
||||
unsigned deopt_index;
|
||||
DeoptimizationInfo(Zone* zone, unsigned pc, unsigned arguments,
|
||||
Safepoint::Kind kind)
|
||||
: pc(pc),
|
||||
arguments(arguments),
|
||||
has_doubles(kind & Safepoint::kWithDoubles),
|
||||
trampoline(-1),
|
||||
indexes(new (zone) ZoneList<int>(8, zone)),
|
||||
registers(kind & Safepoint::kWithRegisters
|
||||
? new (zone) ZoneList<int>(4, zone)
|
||||
: nullptr),
|
||||
deopt_index(Safepoint::kNoDeoptimizationIndex) {}
|
||||
};
|
||||
|
||||
uint32_t EncodeExceptPC(const DeoptimizationInfo& info, unsigned index);
|
||||
uint32_t EncodeExceptPC(const DeoptimizationInfo&);
|
||||
|
||||
bool IsIdenticalExceptForPc(int index1, int index2) const;
|
||||
bool IsIdenticalExceptForPc(const DeoptimizationInfo&,
|
||||
const DeoptimizationInfo&) const;
|
||||
// If all entries are identical, replace them by 1 entry with pc = kMaxUInt32.
|
||||
void RemoveDuplicates();
|
||||
|
||||
ZoneList<DeoptimizationInfo> deoptimization_info_;
|
||||
ZoneList<unsigned> deopt_index_list_;
|
||||
ZoneList<ZoneList<int>*> indexes_;
|
||||
ZoneList<ZoneList<int>*> registers_;
|
||||
|
||||
unsigned offset_;
|
||||
bool emitted_;
|
||||
|
Loading…
Reference in New Issue
Block a user