Commit 50a80c93 authored by Maya Lekova's avatar Maya Lekova Committed by Commit Bot

[turbofan] Make hints equality cheaper using hashing

Put the nesting limit of the serializer back to 25.

Bug: chromium:1034768
Change-Id: I7ea827d27241ea930bae40142069bab1962e4133
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1981156
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65630}
parent 7fcef442
......@@ -6,6 +6,7 @@
#define V8_COMPILER_FUNCTIONAL_LIST_H_
#include <iterator>
#include "src/base/functional.h"
#include "src/zone/zone.h"
namespace v8 {
......@@ -17,7 +18,7 @@ namespace compiler {
// in ML-like languages, with the only difference that it also caches the length
// of the list in each node.
// TODO(tebbi): Use this implementation also for RedundancyElimination.
template <class A>
template <typename A>
class FunctionalList {
private:
struct Cons : ZoneObject {
......
......@@ -4,6 +4,7 @@
#include "src/compiler/serializer-for-background-compilation.h"
#include <functional>
#include <sstream>
#include "src/base/optional.h"
......@@ -298,6 +299,34 @@ class VirtualClosure {
Hints const context_hints_;
};
struct HintsHash {
size_t operator()(Hints const& hints) const {
return base::hash_combine(hints.constants().Hash(), hints.maps().Hash(),
hints.virtual_closures().Hash(),
hints.virtual_contexts().Hash(),
hints.virtual_bound_functions().Hash());
}
};
size_t hash_value(Hints const& hints) { return HintsHash()(hints); }
struct VirtualBoundFunctionHash {
size_t operator()(VirtualBoundFunction const& vbf) const {
return base::hash_combine(HintsHash()(vbf.bound_target),
base::hash_range(vbf.bound_arguments.begin(),
vbf.bound_arguments.end()));
}
};
struct VirtualClosureHash {
size_t operator()(VirtualClosure const& c) const {
return base::hash_combine(
Handle<SharedFunctionInfo>::hash()(c.shared()),
Handle<FeedbackVector>::hash()(c.feedback_vector()),
HintsHash()(c.context_hints()));
}
};
// A CompilationSubject is a VirtualClosure, optionally with a matching
// concrete closure.
class CompilationSubject {
......
......@@ -10,6 +10,7 @@
#ifndef V8_COMPILER_SERIALIZER_HINTS_H_
#define V8_COMPILER_SERIALIZER_HINTS_H_
#include "src/base/functional.h"
#include "src/compiler/functional-list.h"
#include "src/handles/handles.h"
#include "src/zone/zone-containers.h"
......@@ -23,7 +24,7 @@ class Map;
namespace compiler {
template <typename T, typename EqualTo>
template <typename T, typename EqualTo, typename Hasher>
class FunctionalSet {
public:
void Add(T const& elem, Zone* zone) {
......@@ -31,9 +32,12 @@ class FunctionalSet {
if (equal_to(l, elem)) return;
}
data_.PushFront(elem, zone);
// We rely on commutative property of the computed hash, otherwise
// we would use base::hash_combine here.
hash_ = hash_ ^ hasher(elem);
}
void Union(FunctionalSet<T, EqualTo> other, Zone* zone) {
void Union(FunctionalSet<T, EqualTo, Hasher> other, Zone* zone) {
if (!data_.TriviallyEquals(other.data_)) {
// Choose the larger side as tail.
if (data_.Size() < other.data_.Size()) std::swap(data_, other.data_);
......@@ -44,23 +48,25 @@ class FunctionalSet {
bool IsEmpty() const { return data_.begin() == data_.end(); }
// Warning: quadratic time complexity.
bool Includes(FunctionalSet<T, EqualTo> const& other) const {
bool Includes(FunctionalSet<T, EqualTo, Hasher> 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 operator==(const FunctionalSet<T, EqualTo>& other) const {
bool operator==(const FunctionalSet<T, EqualTo, Hasher>& other) const {
return this->data_.TriviallyEquals(other.data_) ||
(this->data_.Size() == other.data_.Size() && this->Includes(other) &&
(this->data_.Size() == other.data_.Size() &&
this->Hash() == other.Hash() && this->Includes(other) &&
other.Includes(*this));
}
bool operator!=(const FunctionalSet<T, EqualTo>& other) const {
bool operator!=(const FunctionalSet<T, EqualTo, Hasher>& other) const {
return !(*this == other);
}
size_t Size() const { return data_.Size(); }
size_t Hash() const { return hash_; }
using iterator = typename FunctionalList<T>::iterator;
......@@ -69,11 +75,16 @@ class FunctionalSet {
private:
static EqualTo equal_to;
static Hasher hasher;
FunctionalList<T> data_;
size_t hash_ = 0;
};
template <typename T, typename EqualTo>
EqualTo FunctionalSet<T, EqualTo>::equal_to;
template <typename T, typename EqualTo, typename Hasher>
EqualTo FunctionalSet<T, EqualTo, Hasher>::equal_to;
template <typename T, typename EqualTo, typename Hasher>
Hasher FunctionalSet<T, EqualTo, Hasher>::hasher;
struct VirtualContext {
unsigned int distance;
......@@ -86,19 +97,32 @@ struct VirtualContext {
bool operator==(const VirtualContext& other) const {
return context.equals(other.context) && distance == other.distance;
}
struct Hash {
size_t operator()(VirtualContext const& c) const {
return base::hash_combine(static_cast<size_t>(c.distance),
Handle<Context>::hash()(c.context));
}
};
};
class VirtualClosure;
struct VirtualClosureHash;
struct VirtualBoundFunction;
struct VirtualBoundFunctionHash;
using ConstantsSet = FunctionalSet<Handle<Object>, Handle<Object>::equal_to>;
using ConstantsSet = FunctionalSet<Handle<Object>, Handle<Object>::equal_to,
Handle<Object>::hash>;
using VirtualContextsSet =
FunctionalSet<VirtualContext, std::equal_to<VirtualContext>>;
using MapsSet = FunctionalSet<Handle<Map>, Handle<Map>::equal_to>;
FunctionalSet<VirtualContext, std::equal_to<VirtualContext>,
VirtualContext::Hash>;
using MapsSet =
FunctionalSet<Handle<Map>, Handle<Map>::equal_to, Handle<Map>::hash>;
using VirtualClosuresSet =
FunctionalSet<VirtualClosure, std::equal_to<VirtualClosure>>;
FunctionalSet<VirtualClosure, std::equal_to<VirtualClosure>,
VirtualClosureHash>;
using VirtualBoundFunctionsSet =
FunctionalSet<VirtualBoundFunction, std::equal_to<VirtualBoundFunction>>;
FunctionalSet<VirtualBoundFunction, std::equal_to<VirtualBoundFunction>,
VirtualBoundFunctionHash>;
struct HintsImpl;
class JSHeapBroker;
......
......@@ -501,7 +501,7 @@ DEFINE_BOOL(block_concurrent_recompilation, false,
"block queued jobs until released")
DEFINE_BOOL(concurrent_inlining, false,
"run optimizing compiler's inlining phase on a separate thread")
DEFINE_INT(max_serializer_nesting, 15,
DEFINE_INT(max_serializer_nesting, 25,
"maximum levels for nesting child serializers")
DEFINE_IMPLICATION(future, concurrent_inlining)
DEFINE_BOOL(trace_heap_broker_verbose, false,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment