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,
|
int arguments,
|
||||||
Safepoint::DeoptMode deopt_mode) {
|
Safepoint::DeoptMode deopt_mode) {
|
||||||
DCHECK_GE(arguments, 0);
|
DCHECK_GE(arguments, 0);
|
||||||
DeoptimizationInfo info;
|
deoptimization_info_.Add(
|
||||||
info.pc = assembler->pc_offset();
|
DeoptimizationInfo(zone_, assembler->pc_offset(), arguments, kind),
|
||||||
info.arguments = arguments;
|
zone_);
|
||||||
info.has_doubles = (kind & Safepoint::kWithDoubles);
|
|
||||||
info.trampoline = -1;
|
|
||||||
deoptimization_info_.Add(info, zone_);
|
|
||||||
deopt_index_list_.Add(Safepoint::kNoDeoptimizationIndex, zone_);
|
|
||||||
if (deopt_mode == Safepoint::kNoLazyDeopt) {
|
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_);
|
DeoptimizationInfo& new_info = deoptimization_info_.last();
|
||||||
registers_.Add((kind & Safepoint::kWithRegisters)
|
return Safepoint(new_info.indexes, new_info.registers);
|
||||||
? new (zone_) ZoneList<int>(4, zone_)
|
|
||||||
: nullptr,
|
|
||||||
zone_);
|
|
||||||
return Safepoint(indexes_.last(), registers_.last());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SafepointTableBuilder::RecordLazyDeoptimizationIndex(int index) {
|
void SafepointTableBuilder::RecordLazyDeoptimizationIndex(int index) {
|
||||||
while (last_lazy_safepoint_ < deopt_index_list_.length()) {
|
while (last_lazy_safepoint_ < deoptimization_info_.length()) {
|
||||||
deopt_index_list_[last_lazy_safepoint_++] = index;
|
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.
|
// Emit sorted table of pc offsets together with deoptimization indexes.
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
assembler->dd(deoptimization_info_[i].pc);
|
const DeoptimizationInfo& info = deoptimization_info_[i];
|
||||||
assembler->dd(EncodeExceptPC(deoptimization_info_[i],
|
assembler->dd(info.pc);
|
||||||
deopt_index_list_[i]));
|
assembler->dd(EncodeExceptPC(info));
|
||||||
assembler->dd(deoptimization_info_[i].trampoline);
|
assembler->dd(info.trampoline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit table of bitmaps.
|
// Emit table of bitmaps.
|
||||||
ZoneList<uint8_t> bits(bytes_per_entry, zone_);
|
ZoneList<uint8_t> bits(bytes_per_entry, zone_);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
ZoneList<int>* indexes = indexes_[i];
|
ZoneList<int>* indexes = deoptimization_info_[i].indexes;
|
||||||
ZoneList<int>* registers = registers_[i];
|
ZoneList<int>* registers = deoptimization_info_[i].registers;
|
||||||
bits.Clear();
|
bits.Clear();
|
||||||
bits.AddBlock(0, bytes_per_entry, zone_);
|
bits.AddBlock(0, bytes_per_entry, zone_);
|
||||||
|
|
||||||
@ -246,13 +238,10 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) {
|
|||||||
emitted_ = true;
|
emitted_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info) {
|
||||||
uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info,
|
return SafepointEntry::DeoptimizationIndexField::encode(info.deopt_index) |
|
||||||
unsigned index) {
|
SafepointEntry::ArgumentsField::encode(info.arguments) |
|
||||||
uint32_t encoding = SafepointEntry::DeoptimizationIndexField::encode(index);
|
SafepointEntry::SaveDoublesField::encode(info.has_doubles);
|
||||||
encoding |= SafepointEntry::ArgumentsField::encode(info.arguments);
|
|
||||||
encoding |= SafepointEntry::SaveDoublesField::encode(info.has_doubles);
|
|
||||||
return encoding;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SafepointTableBuilder::RemoveDuplicates() {
|
void SafepointTableBuilder::RemoveDuplicates() {
|
||||||
@ -262,44 +251,36 @@ void SafepointTableBuilder::RemoveDuplicates() {
|
|||||||
// pointers and without deoptimization info.
|
// pointers and without deoptimization info.
|
||||||
|
|
||||||
int length = deoptimization_info_.length();
|
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;
|
if (length < 2) return;
|
||||||
|
|
||||||
// Check that all entries (1, length] are identical to entry 0.
|
// 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) {
|
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.
|
// entry, and set the pc to kMaxUInt32.
|
||||||
deoptimization_info_.Rewind(1);
|
deoptimization_info_.Rewind(1);
|
||||||
deopt_index_list_.Rewind(1);
|
|
||||||
indexes_.Rewind(1);
|
|
||||||
registers_.Rewind(1);
|
|
||||||
deoptimization_info_[0].pc = kMaxUInt32;
|
deoptimization_info_[0].pc = kMaxUInt32;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SafepointTableBuilder::IsIdenticalExceptForPc(int index1,
|
bool SafepointTableBuilder::IsIdenticalExceptForPc(
|
||||||
int index2) const {
|
const DeoptimizationInfo& info1, const DeoptimizationInfo& info2) const {
|
||||||
DeoptimizationInfo& deopt_info_1 = deoptimization_info_[index1];
|
if (info1.arguments != info2.arguments) return false;
|
||||||
DeoptimizationInfo& deopt_info_2 = deoptimization_info_[index2];
|
if (info1.has_doubles != info2.has_doubles) return false;
|
||||||
if (deopt_info_1.arguments != deopt_info_2.arguments) return false;
|
|
||||||
if (deopt_info_1.has_doubles != deopt_info_2.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>* indexes1 = info1.indexes;
|
||||||
ZoneList<int>* indexes2 = indexes_[index2];
|
ZoneList<int>* indexes2 = info2.indexes;
|
||||||
if (indexes1->length() != indexes2->length()) return false;
|
if (indexes1->length() != indexes2->length()) return false;
|
||||||
for (int i = 0; i < indexes1->length(); ++i) {
|
for (int i = 0; i < indexes1->length(); ++i) {
|
||||||
if (indexes1->at(i) != indexes2->at(i)) return false;
|
if (indexes1->at(i) != indexes2->at(i)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneList<int>* registers1 = registers_[index1];
|
ZoneList<int>* registers1 = info1.registers;
|
||||||
ZoneList<int>* registers2 = registers_[index2];
|
ZoneList<int>* registers2 = info2.registers;
|
||||||
if (registers1) {
|
if (registers1) {
|
||||||
if (!registers2) return false;
|
if (!registers2) return false;
|
||||||
if (registers1->length() != registers2->length()) return false;
|
if (registers1->length() != registers2->length()) return false;
|
||||||
|
@ -194,8 +194,8 @@ class Safepoint BASE_EMBEDDED {
|
|||||||
private:
|
private:
|
||||||
Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers)
|
Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers)
|
||||||
: indexes_(indexes), registers_(registers) {}
|
: indexes_(indexes), registers_(registers) {}
|
||||||
ZoneList<int>* indexes_;
|
ZoneList<int>* const indexes_;
|
||||||
ZoneList<int>* registers_;
|
ZoneList<int>* const registers_;
|
||||||
|
|
||||||
friend class SafepointTableBuilder;
|
friend class SafepointTableBuilder;
|
||||||
};
|
};
|
||||||
@ -205,9 +205,6 @@ class SafepointTableBuilder BASE_EMBEDDED {
|
|||||||
public:
|
public:
|
||||||
explicit SafepointTableBuilder(Zone* zone)
|
explicit SafepointTableBuilder(Zone* zone)
|
||||||
: deoptimization_info_(32, zone),
|
: deoptimization_info_(32, zone),
|
||||||
deopt_index_list_(32, zone),
|
|
||||||
indexes_(32, zone),
|
|
||||||
registers_(32, zone),
|
|
||||||
emitted_(false),
|
emitted_(false),
|
||||||
last_lazy_safepoint_(0),
|
last_lazy_safepoint_(0),
|
||||||
zone_(zone) { }
|
zone_(zone) { }
|
||||||
@ -225,7 +222,7 @@ class SafepointTableBuilder BASE_EMBEDDED {
|
|||||||
// outstanding safepoints.
|
// outstanding safepoints.
|
||||||
void RecordLazyDeoptimizationIndex(int index);
|
void RecordLazyDeoptimizationIndex(int index);
|
||||||
void BumpLastLazySafepointIndex() {
|
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
|
// Emit the safepoint table after the body. The number of bits per
|
||||||
@ -244,18 +241,30 @@ class SafepointTableBuilder BASE_EMBEDDED {
|
|||||||
unsigned arguments;
|
unsigned arguments;
|
||||||
bool has_doubles;
|
bool has_doubles;
|
||||||
int trampoline;
|
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.
|
// If all entries are identical, replace them by 1 entry with pc = kMaxUInt32.
|
||||||
void RemoveDuplicates();
|
void RemoveDuplicates();
|
||||||
|
|
||||||
ZoneList<DeoptimizationInfo> deoptimization_info_;
|
ZoneList<DeoptimizationInfo> deoptimization_info_;
|
||||||
ZoneList<unsigned> deopt_index_list_;
|
|
||||||
ZoneList<ZoneList<int>*> indexes_;
|
|
||||||
ZoneList<ZoneList<int>*> registers_;
|
|
||||||
|
|
||||||
unsigned offset_;
|
unsigned offset_;
|
||||||
bool emitted_;
|
bool emitted_;
|
||||||
|
Loading…
Reference in New Issue
Block a user