[turbofan] Switch serializer hints to FunctionalSet
Bug: v8:9720 Change-Id: I681c521c7d368148d41aaa4a0694194e33d9a091 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1800578 Commit-Queue: Maya Lekova <mslekova@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#63824}
This commit is contained in:
parent
9febc505bd
commit
f5a8402350
@ -90,6 +90,8 @@ class FunctionalList {
|
||||
|
||||
size_t Size() const { return elements_ ? elements_->size : 0; }
|
||||
|
||||
void Clear() { elements_ = nullptr; }
|
||||
|
||||
class iterator {
|
||||
public:
|
||||
explicit iterator(Cons* cur) : current_(cur) {}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "src/compiler/access-info.h"
|
||||
#include "src/compiler/bytecode-analysis.h"
|
||||
#include "src/compiler/compilation-dependencies.h"
|
||||
#include "src/compiler/functional-list.h"
|
||||
#include "src/compiler/js-heap-broker.h"
|
||||
#include "src/handles/handles-inl.h"
|
||||
#include "src/ic/call-optimization.h"
|
||||
@ -230,13 +231,41 @@ namespace compiler {
|
||||
UNCONDITIONAL_JUMPS_LIST(V) \
|
||||
UNREACHABLE_BYTECODE_LIST(V)
|
||||
|
||||
template <typename T>
|
||||
struct HandleComparator {
|
||||
bool operator()(const Handle<T>& lhs, const Handle<T>& rhs) const {
|
||||
return lhs.address() < rhs.address();
|
||||
template <typename T, typename EqualTo>
|
||||
class FunctionalSet {
|
||||
public:
|
||||
void Add(T const& elem, Zone* zone) {
|
||||
for (auto const& l : data_) {
|
||||
if (equal_to(l, elem)) return;
|
||||
}
|
||||
data_.PushFront(elem, zone);
|
||||
}
|
||||
|
||||
bool Includes(FunctionalSet<T, EqualTo> const& other) const {
|
||||
return std::all_of(other.begin(), other.end(), [&](T const& other_elem) {
|
||||
return std::any_of(this->begin(), this->end(), [&](T const& this_elem) {
|
||||
return equal_to(this_elem, other_elem);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
bool IsEmpty() const { return data_.begin() == data_.end(); }
|
||||
|
||||
void Clear() { data_.Clear(); }
|
||||
|
||||
using iterator = typename FunctionalList<T>::iterator;
|
||||
|
||||
iterator begin() const { return data_.begin(); }
|
||||
iterator end() const { return data_.end(); }
|
||||
|
||||
private:
|
||||
static EqualTo equal_to;
|
||||
FunctionalList<T> data_;
|
||||
};
|
||||
|
||||
template <typename T, typename EqualTo>
|
||||
EqualTo FunctionalSet<T, EqualTo>::equal_to;
|
||||
|
||||
struct VirtualContext {
|
||||
unsigned int distance;
|
||||
Handle<Context> context;
|
||||
@ -245,21 +274,22 @@ struct VirtualContext {
|
||||
: distance(distance_in), context(context_in) {
|
||||
CHECK_GT(distance, 0);
|
||||
}
|
||||
bool operator<(const VirtualContext& other) const {
|
||||
return HandleComparator<Context>()(context, other.context) &&
|
||||
distance < other.distance;
|
||||
bool operator==(const VirtualContext& other) const {
|
||||
return context.equals(other.context) && distance == other.distance;
|
||||
}
|
||||
};
|
||||
|
||||
class FunctionBlueprint;
|
||||
using ConstantsSet = ZoneSet<Handle<Object>, HandleComparator<Object>>;
|
||||
using VirtualContextsSet = ZoneSet<VirtualContext>;
|
||||
using MapsSet = ZoneSet<Handle<Map>, HandleComparator<Map>>;
|
||||
using BlueprintsSet = ZoneSet<FunctionBlueprint>;
|
||||
using ConstantsSet = FunctionalSet<Handle<Object>, Handle<Object>::equal_to>;
|
||||
using VirtualContextsSet =
|
||||
FunctionalSet<VirtualContext, std::equal_to<VirtualContext>>;
|
||||
using MapsSet = FunctionalSet<Handle<Map>, Handle<Map>::equal_to>;
|
||||
using BlueprintsSet =
|
||||
FunctionalSet<FunctionBlueprint, std::equal_to<FunctionBlueprint>>;
|
||||
|
||||
class Hints {
|
||||
public:
|
||||
explicit Hints(Zone* zone);
|
||||
Hints() = default;
|
||||
|
||||
static Hints SingleConstant(Handle<Object> constant, Zone* zone);
|
||||
|
||||
@ -268,12 +298,12 @@ class Hints {
|
||||
const BlueprintsSet& function_blueprints() const;
|
||||
const VirtualContextsSet& virtual_contexts() const;
|
||||
|
||||
void AddConstant(Handle<Object> constant);
|
||||
void AddMap(Handle<Map> map);
|
||||
void AddFunctionBlueprint(FunctionBlueprint function_blueprint);
|
||||
void AddVirtualContext(VirtualContext virtual_context);
|
||||
void AddConstant(Handle<Object> constant, Zone* zone);
|
||||
void AddMap(Handle<Map> map, Zone* zone);
|
||||
void AddFunctionBlueprint(FunctionBlueprint function_blueprint, Zone* zone);
|
||||
void AddVirtualContext(VirtualContext virtual_context, Zone* zone);
|
||||
|
||||
void Add(const Hints& other);
|
||||
void Add(const Hints& other, Zone* zone);
|
||||
|
||||
void Clear();
|
||||
bool IsEmpty() const;
|
||||
@ -304,13 +334,12 @@ class FunctionBlueprint {
|
||||
Handle<FeedbackVector> feedback_vector() const { return feedback_vector_; }
|
||||
const Hints& context_hints() const { return context_hints_; }
|
||||
|
||||
bool operator<(const FunctionBlueprint& other) const {
|
||||
bool operator==(const FunctionBlueprint& other) const {
|
||||
// A feedback vector is never used for more than one SFI, so it can
|
||||
// be used for strict ordering of blueprints.
|
||||
// be used for equality of blueprints.
|
||||
DCHECK_IMPLIES(feedback_vector_.equals(other.feedback_vector_),
|
||||
shared_.equals(other.shared_));
|
||||
return HandleComparator<FeedbackVector>()(feedback_vector_,
|
||||
other.feedback_vector_);
|
||||
return feedback_vector_.equals(other.feedback_vector_);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -511,8 +540,8 @@ FunctionBlueprint::FunctionBlueprint(Handle<JSFunction> function,
|
||||
Isolate* isolate, Zone* zone)
|
||||
: shared_(handle(function->shared(), isolate)),
|
||||
feedback_vector_(handle(function->feedback_vector(), isolate)),
|
||||
context_hints_(zone) {
|
||||
context_hints_.AddConstant(handle(function->context(), isolate));
|
||||
context_hints_() {
|
||||
context_hints_.AddConstant(handle(function->context(), isolate), zone);
|
||||
}
|
||||
|
||||
CompilationSubject::CompilationSubject(Handle<JSFunction> closure,
|
||||
@ -521,25 +550,11 @@ CompilationSubject::CompilationSubject(Handle<JSFunction> closure,
|
||||
CHECK(closure->has_feedback_vector());
|
||||
}
|
||||
|
||||
Hints::Hints(Zone* zone)
|
||||
: virtual_contexts_(zone),
|
||||
constants_(zone),
|
||||
maps_(zone),
|
||||
function_blueprints_(zone) {}
|
||||
|
||||
#ifdef ENABLE_SLOW_DCHECKS
|
||||
namespace {
|
||||
template <typename K, typename Compare>
|
||||
bool SetIncludes(ZoneSet<K, Compare> const& lhs,
|
||||
ZoneSet<K, Compare> const& rhs) {
|
||||
return std::all_of(rhs.cbegin(), rhs.cend(),
|
||||
[&](K const& x) { return lhs.find(x) != lhs.cend(); });
|
||||
}
|
||||
} // namespace
|
||||
bool Hints::Includes(Hints const& other) const {
|
||||
return SetIncludes(constants(), other.constants()) &&
|
||||
SetIncludes(function_blueprints(), other.function_blueprints()) &&
|
||||
SetIncludes(maps(), other.maps());
|
||||
return constants().Includes(other.constants()) &&
|
||||
function_blueprints().Includes(other.function_blueprints()) &&
|
||||
maps().Includes(other.maps());
|
||||
}
|
||||
bool Hints::Equals(Hints const& other) const {
|
||||
return this->Includes(other) && other.Includes(*this);
|
||||
@ -547,8 +562,8 @@ bool Hints::Equals(Hints const& other) const {
|
||||
#endif
|
||||
|
||||
Hints Hints::SingleConstant(Handle<Object> constant, Zone* zone) {
|
||||
Hints result(zone);
|
||||
result.AddConstant(constant);
|
||||
Hints result;
|
||||
result.AddConstant(constant, zone);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -564,30 +579,31 @@ const VirtualContextsSet& Hints::virtual_contexts() const {
|
||||
return virtual_contexts_;
|
||||
}
|
||||
|
||||
void Hints::AddVirtualContext(VirtualContext virtual_context) {
|
||||
virtual_contexts_.insert(virtual_context);
|
||||
void Hints::AddVirtualContext(VirtualContext virtual_context, Zone* zone) {
|
||||
virtual_contexts_.Add(virtual_context, zone);
|
||||
}
|
||||
|
||||
void Hints::AddConstant(Handle<Object> constant) {
|
||||
constants_.insert(constant);
|
||||
void Hints::AddConstant(Handle<Object> constant, Zone* zone) {
|
||||
constants_.Add(constant, zone);
|
||||
}
|
||||
|
||||
void Hints::AddMap(Handle<Map> map) { maps_.insert(map); }
|
||||
void Hints::AddMap(Handle<Map> map, Zone* zone) { maps_.Add(map, zone); }
|
||||
|
||||
void Hints::AddFunctionBlueprint(FunctionBlueprint function_blueprint) {
|
||||
function_blueprints_.insert(function_blueprint);
|
||||
void Hints::AddFunctionBlueprint(FunctionBlueprint function_blueprint,
|
||||
Zone* zone) {
|
||||
function_blueprints_.Add(function_blueprint, zone);
|
||||
}
|
||||
|
||||
void Hints::Add(const Hints& other) {
|
||||
for (auto x : other.constants()) AddConstant(x);
|
||||
for (auto x : other.maps()) AddMap(x);
|
||||
for (auto x : other.function_blueprints()) AddFunctionBlueprint(x);
|
||||
for (auto x : other.virtual_contexts()) AddVirtualContext(x);
|
||||
void Hints::Add(const Hints& other, Zone* zone) {
|
||||
for (auto x : other.constants()) AddConstant(x, zone);
|
||||
for (auto x : other.maps()) AddMap(x, zone);
|
||||
for (auto x : other.function_blueprints()) AddFunctionBlueprint(x, zone);
|
||||
for (auto x : other.virtual_contexts()) AddVirtualContext(x, zone);
|
||||
}
|
||||
|
||||
bool Hints::IsEmpty() const {
|
||||
return constants().empty() && maps().empty() &&
|
||||
function_blueprints().empty() && virtual_contexts().empty();
|
||||
return constants().IsEmpty() && maps().IsEmpty() &&
|
||||
function_blueprints().IsEmpty() && virtual_contexts().IsEmpty();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out,
|
||||
@ -625,10 +641,10 @@ std::ostream& operator<<(std::ostream& out, const Hints& hints) {
|
||||
}
|
||||
|
||||
void Hints::Clear() {
|
||||
virtual_contexts_.clear();
|
||||
constants_.clear();
|
||||
maps_.clear();
|
||||
function_blueprints_.clear();
|
||||
virtual_contexts_.Clear();
|
||||
constants_.Clear();
|
||||
maps_.Clear();
|
||||
function_blueprints_.Clear();
|
||||
DCHECK(IsEmpty());
|
||||
}
|
||||
|
||||
@ -648,7 +664,7 @@ class SerializerForBackgroundCompilation::Environment : public ZoneObject {
|
||||
|
||||
void Revive() {
|
||||
DCHECK(IsDead());
|
||||
ephemeral_hints_.resize(ephemeral_hints_size(), Hints(zone()));
|
||||
ephemeral_hints_.resize(ephemeral_hints_size(), Hints());
|
||||
DCHECK(!IsDead());
|
||||
}
|
||||
|
||||
@ -691,7 +707,6 @@ class SerializerForBackgroundCompilation::Environment : public ZoneObject {
|
||||
|
||||
int RegisterToLocalIndex(interpreter::Register reg) const;
|
||||
|
||||
Zone* zone() const { return zone_; }
|
||||
int parameter_count() const { return parameter_count_; }
|
||||
int register_count() const { return register_count_; }
|
||||
|
||||
@ -722,19 +737,19 @@ SerializerForBackgroundCompilation::Environment::Environment(
|
||||
parameter_count_(
|
||||
function_.shared()->GetBytecodeArray().parameter_count()),
|
||||
register_count_(function_.shared()->GetBytecodeArray().register_count()),
|
||||
closure_hints_(zone),
|
||||
current_context_hints_(zone),
|
||||
return_value_hints_(zone),
|
||||
ephemeral_hints_(ephemeral_hints_size(), Hints(zone), zone) {
|
||||
closure_hints_(),
|
||||
current_context_hints_(),
|
||||
return_value_hints_(),
|
||||
ephemeral_hints_(ephemeral_hints_size(), Hints(), zone) {
|
||||
Handle<JSFunction> closure;
|
||||
if (function.closure().ToHandle(&closure)) {
|
||||
closure_hints_.AddConstant(closure);
|
||||
closure_hints_.AddConstant(closure, zone);
|
||||
} else {
|
||||
closure_hints_.AddFunctionBlueprint(function.blueprint());
|
||||
closure_hints_.AddFunctionBlueprint(function.blueprint(), zone);
|
||||
}
|
||||
|
||||
// Consume blueprint context hint information.
|
||||
current_context_hints().Add(function.blueprint().context_hints());
|
||||
current_context_hints().Add(function.blueprint().context_hints(), zone);
|
||||
}
|
||||
|
||||
SerializerForBackgroundCompilation::Environment::Environment(
|
||||
@ -762,7 +777,7 @@ SerializerForBackgroundCompilation::Environment::Environment(
|
||||
if (new_target_reg.is_valid()) {
|
||||
DCHECK(register_hints(new_target_reg).IsEmpty());
|
||||
if (new_target.has_value()) {
|
||||
register_hints(new_target_reg).Add(*new_target);
|
||||
register_hints(new_target_reg).Add(*new_target, zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -785,10 +800,10 @@ void SerializerForBackgroundCompilation::Environment::Merge(
|
||||
|
||||
CHECK_EQ(ephemeral_hints_.size(), other->ephemeral_hints_.size());
|
||||
for (size_t i = 0; i < ephemeral_hints_.size(); ++i) {
|
||||
ephemeral_hints_[i].Add(other->ephemeral_hints_[i]);
|
||||
ephemeral_hints_[i].Add(other->ephemeral_hints_[i], zone_);
|
||||
}
|
||||
|
||||
return_value_hints_.Add(other->return_value_hints_);
|
||||
return_value_hints_.Add(other->return_value_hints_, zone_);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(
|
||||
@ -908,7 +923,7 @@ Hints SerializerForBackgroundCompilation::Run() {
|
||||
TRACE_BROKER(broker(), "Already ran serializer for SharedFunctionInfo "
|
||||
<< Brief(*shared.object())
|
||||
<< ", bailing out.\n");
|
||||
return Hints(zone());
|
||||
return Hints();
|
||||
}
|
||||
shared.SetSerializedForCompilation(feedback_vector_ref);
|
||||
|
||||
@ -1044,7 +1059,7 @@ void SerializerForBackgroundCompilation::VisitGetIterator(
|
||||
AccessMode::kLoad);
|
||||
if (environment()->IsDead()) return;
|
||||
|
||||
const Hints& callee = Hints(zone());
|
||||
const Hints& callee = Hints();
|
||||
FeedbackSlot call_slot = iterator->GetSlotOperand(2);
|
||||
HintsVector parameters({receiver}, zone());
|
||||
ProcessCallOrConstruct(callee, base::nullopt, parameters, call_slot);
|
||||
@ -1063,7 +1078,7 @@ void SerializerForBackgroundCompilation::VisitGetSuperConstructor(
|
||||
map.SerializePrototype();
|
||||
ObjectRef proto = map.prototype();
|
||||
if (proto.IsHeapObject() && proto.AsHeapObject().map().is_constructor()) {
|
||||
environment()->register_hints(dst).AddConstant(proto.object());
|
||||
environment()->register_hints(dst).AddConstant(proto.object(), zone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1079,56 +1094,59 @@ void SerializerForBackgroundCompilation::VisitGetTemplateObject(
|
||||
shared.GetTemplateObject(description, feedback_vector_ref, slot,
|
||||
SerializationPolicy::kSerializeIfNeeded);
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().AddConstant(template_object.object());
|
||||
environment()->accumulator_hints().AddConstant(template_object.object(),
|
||||
zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitLdaTrue(
|
||||
BytecodeArrayIterator* iterator) {
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().AddConstant(
|
||||
broker()->isolate()->factory()->true_value());
|
||||
broker()->isolate()->factory()->true_value(), zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitLdaFalse(
|
||||
BytecodeArrayIterator* iterator) {
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().AddConstant(
|
||||
broker()->isolate()->factory()->false_value());
|
||||
broker()->isolate()->factory()->false_value(), zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitLdaTheHole(
|
||||
BytecodeArrayIterator* iterator) {
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().AddConstant(
|
||||
broker()->isolate()->factory()->the_hole_value());
|
||||
broker()->isolate()->factory()->the_hole_value(), zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitLdaUndefined(
|
||||
BytecodeArrayIterator* iterator) {
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().AddConstant(
|
||||
broker()->isolate()->factory()->undefined_value());
|
||||
broker()->isolate()->factory()->undefined_value(), zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitLdaNull(
|
||||
BytecodeArrayIterator* iterator) {
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().AddConstant(
|
||||
broker()->isolate()->factory()->null_value());
|
||||
broker()->isolate()->factory()->null_value(), zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitLdaZero(
|
||||
BytecodeArrayIterator* iterator) {
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().AddConstant(
|
||||
handle(Smi::FromInt(0), broker()->isolate()));
|
||||
handle(Smi::FromInt(0), broker()->isolate()), zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitLdaSmi(
|
||||
BytecodeArrayIterator* iterator) {
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().AddConstant(handle(
|
||||
Smi::FromInt(iterator->GetImmediateOperand(0)), broker()->isolate()));
|
||||
environment()->accumulator_hints().AddConstant(
|
||||
handle(Smi::FromInt(iterator->GetImmediateOperand(0)),
|
||||
broker()->isolate()),
|
||||
zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitInvokeIntrinsic(
|
||||
@ -1221,7 +1239,7 @@ void SerializerForBackgroundCompilation::VisitLdaConstant(
|
||||
ObjectRef object(
|
||||
broker(), iterator->GetConstantForIndexOperand(0, broker()->isolate()));
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().AddConstant(object.object());
|
||||
environment()->accumulator_hints().AddConstant(object.object(), zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitPushContext(
|
||||
@ -1231,12 +1249,12 @@ void SerializerForBackgroundCompilation::VisitPushContext(
|
||||
Hints& saved_context_hints =
|
||||
environment()->register_hints(iterator->GetRegisterOperand(0));
|
||||
saved_context_hints.Clear();
|
||||
saved_context_hints.Add(current_context_hints);
|
||||
saved_context_hints.Add(current_context_hints, zone());
|
||||
|
||||
// New context is in the accumulator. Put those hints into the current context
|
||||
// register hints.
|
||||
current_context_hints.Clear();
|
||||
current_context_hints.Add(environment()->accumulator_hints());
|
||||
current_context_hints.Add(environment()->accumulator_hints(), zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitPopContext(
|
||||
@ -1245,7 +1263,7 @@ void SerializerForBackgroundCompilation::VisitPopContext(
|
||||
Hints& new_context_hints =
|
||||
environment()->register_hints(iterator->GetRegisterOperand(0));
|
||||
environment()->current_context_hints().Clear();
|
||||
environment()->current_context_hints().Add(new_context_hints);
|
||||
environment()->current_context_hints().Add(new_context_hints, zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::ProcessImmutableLoad(
|
||||
@ -1257,7 +1275,7 @@ void SerializerForBackgroundCompilation::ProcessImmutableLoad(
|
||||
|
||||
// If requested, record the object as a hint for the result value.
|
||||
if (result_hints != nullptr && slot_value.has_value()) {
|
||||
result_hints->AddConstant(slot_value.value().object());
|
||||
result_hints->AddConstant(slot_value.value().object(), zone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1300,11 +1318,11 @@ void SerializerForBackgroundCompilation::VisitLdaContextSlot(
|
||||
environment()->register_hints(iterator->GetRegisterOperand(0));
|
||||
const int slot = iterator->GetIndexOperand(1);
|
||||
const int depth = iterator->GetUnsignedImmediateOperand(2);
|
||||
Hints new_accumulator_hints(zone());
|
||||
Hints new_accumulator_hints;
|
||||
ProcessContextAccess(context_hints, slot, depth, kIgnoreSlot,
|
||||
&new_accumulator_hints);
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints);
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints, zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitLdaCurrentContextSlot(
|
||||
@ -1312,11 +1330,11 @@ void SerializerForBackgroundCompilation::VisitLdaCurrentContextSlot(
|
||||
const int slot = iterator->GetIndexOperand(0);
|
||||
const int depth = 0;
|
||||
Hints const& context_hints = environment()->current_context_hints();
|
||||
Hints new_accumulator_hints(zone());
|
||||
Hints new_accumulator_hints;
|
||||
ProcessContextAccess(context_hints, slot, depth, kIgnoreSlot,
|
||||
&new_accumulator_hints);
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints);
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints, zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitLdaImmutableContextSlot(
|
||||
@ -1325,11 +1343,11 @@ void SerializerForBackgroundCompilation::VisitLdaImmutableContextSlot(
|
||||
const int depth = iterator->GetUnsignedImmediateOperand(2);
|
||||
Hints const& context_hints =
|
||||
environment()->register_hints(iterator->GetRegisterOperand(0));
|
||||
Hints new_accumulator_hints(zone());
|
||||
Hints new_accumulator_hints;
|
||||
ProcessContextAccess(context_hints, slot, depth, kSerializeSlot,
|
||||
&new_accumulator_hints);
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints);
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints, zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitLdaImmutableCurrentContextSlot(
|
||||
@ -1337,11 +1355,11 @@ void SerializerForBackgroundCompilation::VisitLdaImmutableCurrentContextSlot(
|
||||
const int slot = iterator->GetIndexOperand(0);
|
||||
const int depth = 0;
|
||||
Hints const& context_hints = environment()->current_context_hints();
|
||||
Hints new_accumulator_hints(zone());
|
||||
Hints new_accumulator_hints;
|
||||
ProcessContextAccess(context_hints, slot, depth, kSerializeSlot,
|
||||
&new_accumulator_hints);
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints);
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints, zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::ProcessModuleVariableAccess(
|
||||
@ -1350,7 +1368,7 @@ void SerializerForBackgroundCompilation::ProcessModuleVariableAccess(
|
||||
const int depth = iterator->GetUnsignedImmediateOperand(1);
|
||||
Hints const& context_hints = environment()->current_context_hints();
|
||||
|
||||
Hints result_hints(zone());
|
||||
Hints result_hints;
|
||||
ProcessContextAccess(context_hints, slot, depth, kSerializeSlot,
|
||||
&result_hints);
|
||||
for (Handle<Object> constant : result_hints.constants()) {
|
||||
@ -1398,14 +1416,15 @@ void SerializerForBackgroundCompilation::VisitLdar(
|
||||
BytecodeArrayIterator* iterator) {
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().Add(
|
||||
environment()->register_hints(iterator->GetRegisterOperand(0)));
|
||||
environment()->register_hints(iterator->GetRegisterOperand(0)), zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitStar(
|
||||
BytecodeArrayIterator* iterator) {
|
||||
interpreter::Register reg = iterator->GetRegisterOperand(0);
|
||||
environment()->register_hints(reg).Clear();
|
||||
environment()->register_hints(reg).Add(environment()->accumulator_hints());
|
||||
environment()->register_hints(reg).Add(environment()->accumulator_hints(),
|
||||
zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitMov(
|
||||
@ -1413,7 +1432,8 @@ void SerializerForBackgroundCompilation::VisitMov(
|
||||
interpreter::Register src = iterator->GetRegisterOperand(0);
|
||||
interpreter::Register dst = iterator->GetRegisterOperand(1);
|
||||
environment()->register_hints(dst).Clear();
|
||||
environment()->register_hints(dst).Add(environment()->register_hints(src));
|
||||
environment()->register_hints(dst).Add(environment()->register_hints(src),
|
||||
zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitCreateRegExpLiteral(
|
||||
@ -1496,7 +1516,8 @@ void SerializerForBackgroundCompilation::ProcessCreateContext(
|
||||
for (auto x : current_context_hints.constants()) {
|
||||
if (x->IsContext()) {
|
||||
Handle<Context> as_context(Handle<Context>::cast(x));
|
||||
accumulator_hints.AddVirtualContext(VirtualContext(1, as_context));
|
||||
accumulator_hints.AddVirtualContext(VirtualContext(1, as_context),
|
||||
zone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1504,7 +1525,7 @@ void SerializerForBackgroundCompilation::ProcessCreateContext(
|
||||
// it of distance {existing distance} + 1.
|
||||
for (auto x : current_context_hints.virtual_contexts()) {
|
||||
accumulator_hints.AddVirtualContext(
|
||||
VirtualContext(x.distance + 1, x.context));
|
||||
VirtualContext(x.distance + 1, x.context), zone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1524,7 +1545,7 @@ void SerializerForBackgroundCompilation::VisitCreateClosure(
|
||||
FunctionBlueprint blueprint(shared,
|
||||
Handle<FeedbackVector>::cast(cell_value),
|
||||
environment()->current_context_hints());
|
||||
environment()->accumulator_hints().AddFunctionBlueprint(blueprint);
|
||||
environment()->accumulator_hints().AddFunctionBlueprint(blueprint, zone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1697,7 +1718,7 @@ Hints SerializerForBackgroundCompilation::RunChildSerializer(
|
||||
// Fill the rest with empty hints.
|
||||
padded.resize(
|
||||
function.blueprint().shared()->GetBytecodeArray().parameter_count(),
|
||||
Hints(zone()));
|
||||
Hints());
|
||||
return RunChildSerializer(function, new_target, padded, false);
|
||||
}
|
||||
|
||||
@ -1788,11 +1809,11 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
|
||||
// site, and it may make sense to add the Array JSFunction constant.
|
||||
if (new_target.has_value()) {
|
||||
// Construct; feedback is new_target, which often is also the callee.
|
||||
new_target->AddConstant(target->object());
|
||||
callee.AddConstant(target->object());
|
||||
new_target->AddConstant(target->object(), zone());
|
||||
callee.AddConstant(target->object(), zone());
|
||||
} else {
|
||||
// Call; target is callee.
|
||||
callee.AddConstant(target->object());
|
||||
callee.AddConstant(target->object(), zone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1823,9 +1844,11 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
|
||||
|
||||
if (ProcessCalleeForCallOrConstruct(function, *actual_arguments,
|
||||
speculation_mode)) {
|
||||
environment()->accumulator_hints().Add(RunChildSerializer(
|
||||
CompilationSubject(function, broker()->isolate(), zone()), new_target,
|
||||
*actual_arguments, with_spread));
|
||||
environment()->accumulator_hints().Add(
|
||||
RunChildSerializer(
|
||||
CompilationSubject(function, broker()->isolate(), zone()),
|
||||
new_target, *actual_arguments, with_spread),
|
||||
zone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1836,8 +1859,10 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
|
||||
continue;
|
||||
}
|
||||
|
||||
environment()->accumulator_hints().Add(RunChildSerializer(
|
||||
CompilationSubject(hint), new_target, arguments, with_spread));
|
||||
environment()->accumulator_hints().Add(
|
||||
RunChildSerializer(CompilationSubject(hint), new_target, arguments,
|
||||
with_spread),
|
||||
zone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2279,7 +2304,8 @@ void SerializerForBackgroundCompilation::ProcessJump(
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitReturn(
|
||||
BytecodeArrayIterator* iterator) {
|
||||
environment()->return_value_hints().Add(environment()->accumulator_hints());
|
||||
environment()->return_value_hints().Add(environment()->accumulator_hints(),
|
||||
zone());
|
||||
environment()->ClearEphemeralHints();
|
||||
}
|
||||
|
||||
@ -2351,7 +2377,7 @@ void SerializerForBackgroundCompilation::ProcessGlobalAccess(FeedbackSlot slot,
|
||||
base::Optional<ObjectRef> value =
|
||||
feedback.AsGlobalAccess().GetConstantHint();
|
||||
if (value.has_value()) {
|
||||
environment()->accumulator_hints().AddConstant(value->object());
|
||||
environment()->accumulator_hints().AddConstant(value->object(), zone());
|
||||
}
|
||||
} else {
|
||||
DCHECK(feedback.IsInsufficient());
|
||||
@ -2504,7 +2530,7 @@ SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
|
||||
base::Optional<PropertyCellRef> cell = global_proxy.GetPropertyCell(
|
||||
name, SerializationPolicy::kSerializeIfNeeded);
|
||||
if (access_mode == AccessMode::kLoad && cell.has_value()) {
|
||||
new_accumulator_hints->AddConstant(cell->value().object());
|
||||
new_accumulator_hints->AddConstant(cell->value().object(), zone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2562,7 +2588,7 @@ SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
|
||||
access_info.field_representation(), access_info.field_index(),
|
||||
SerializationPolicy::kSerializeIfNeeded));
|
||||
if (constant.has_value()) {
|
||||
new_accumulator_hints->AddConstant(constant->object());
|
||||
new_accumulator_hints->AddConstant(constant->object(), zone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2592,7 +2618,7 @@ void SerializerForBackgroundCompilation::ProcessKeyedPropertyAccess(
|
||||
return;
|
||||
}
|
||||
|
||||
Hints new_accumulator_hints(zone());
|
||||
Hints new_accumulator_hints;
|
||||
switch (feedback.kind()) {
|
||||
case ProcessedFeedback::kElementAccess:
|
||||
ProcessElementAccess(receiver, key, feedback.AsElementAccess(),
|
||||
@ -2610,7 +2636,7 @@ void SerializerForBackgroundCompilation::ProcessKeyedPropertyAccess(
|
||||
|
||||
if (access_mode == AccessMode::kLoad) {
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints);
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints, zone());
|
||||
} else {
|
||||
DCHECK(new_accumulator_hints.IsEmpty());
|
||||
}
|
||||
@ -2625,7 +2651,7 @@ void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess(
|
||||
broker()->ProcessFeedbackForPropertyAccess(source, access_mode, name);
|
||||
if (BailoutOnUninitialized(feedback)) return;
|
||||
|
||||
Hints new_accumulator_hints(zone());
|
||||
Hints new_accumulator_hints;
|
||||
switch (feedback.kind()) {
|
||||
case ProcessedFeedback::kNamedAccess:
|
||||
DCHECK(name.equals(feedback.AsNamedAccess().name()));
|
||||
@ -2640,7 +2666,7 @@ void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess(
|
||||
|
||||
if (access_mode == AccessMode::kLoad) {
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints);
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints, zone());
|
||||
} else {
|
||||
DCHECK(new_accumulator_hints.IsEmpty());
|
||||
}
|
||||
@ -2677,7 +2703,8 @@ void SerializerForBackgroundCompilation::ProcessNamedAccess(
|
||||
JSFunctionRef function = object.AsJSFunction();
|
||||
function.Serialize();
|
||||
if (new_accumulator_hints != nullptr && function.has_prototype()) {
|
||||
new_accumulator_hints->AddConstant(function.prototype().object());
|
||||
new_accumulator_hints->AddConstant(function.prototype().object(),
|
||||
zone());
|
||||
}
|
||||
}
|
||||
// TODO(neis): Also record accumulator hint for string.length and maybe
|
||||
@ -2861,7 +2888,7 @@ void SerializerForBackgroundCompilation::VisitTestInstanceOf(
|
||||
environment()->register_hints(iterator->GetRegisterOperand(0));
|
||||
Hints rhs = environment()->accumulator_hints();
|
||||
FeedbackSlot slot = iterator->GetSlotOperand(1);
|
||||
Hints new_accumulator_hints(zone());
|
||||
Hints new_accumulator_hints;
|
||||
|
||||
if (slot.IsInvalid() || feedback_vector().is_null()) return;
|
||||
FeedbackSource source(feedback_vector(), slot);
|
||||
@ -2873,7 +2900,7 @@ void SerializerForBackgroundCompilation::VisitTestInstanceOf(
|
||||
InstanceOfFeedback const& rhs_feedback = feedback.AsInstanceOf();
|
||||
if (rhs_feedback.value().has_value()) {
|
||||
Handle<JSObject> constructor = rhs_feedback.value()->object();
|
||||
rhs.AddConstant(constructor);
|
||||
rhs.AddConstant(constructor, zone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2885,7 +2912,7 @@ void SerializerForBackgroundCompilation::VisitTestInstanceOf(
|
||||
if (walk_prototypes) ProcessHintsForHasInPrototypeChain(lhs);
|
||||
|
||||
environment()->accumulator_hints().Clear();
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints);
|
||||
environment()->accumulator_hints().Add(new_accumulator_hints, zone());
|
||||
}
|
||||
|
||||
void SerializerForBackgroundCompilation::VisitToNumeric(
|
||||
|
Loading…
Reference in New Issue
Block a user