Commit 6ea0d55d authored by jkummerow's avatar jkummerow Committed by Commit bot

Fasterify ICSlotCache

Use a hash map instead of a list for faster lookups.

BUG=chromium:517406
LOG=n
R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/1279763006

Cr-Commit-Position: refs/heads/master@{#30078}
parent 82100c15
......@@ -15,7 +15,7 @@ class AstNumberingVisitor final : public AstVisitor {
: AstVisitor(),
next_id_(BailoutId::FirstUsable().ToInt()),
properties_(zone),
ic_slot_cache_(4),
ic_slot_cache_(zone),
dont_optimize_reason_(kNoReason) {
InitializeAstVisitor(isolate, zone);
}
......
......@@ -102,7 +102,7 @@ void VariableProxy::SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
ICSlotCache* cache) {
variable_feedback_slot_ = slot;
if (var()->IsUnallocated()) {
cache->Add(VariableICSlotPair(var(), slot));
cache->Put(var(), slot);
}
}
......@@ -113,12 +113,11 @@ FeedbackVectorRequirements VariableProxy::ComputeFeedbackRequirements(
// VariableProxies that point to the same Variable within a function can
// make their loads from the same IC slot.
if (var()->IsUnallocated()) {
for (int i = 0; i < cache->length(); i++) {
VariableICSlotPair& pair = cache->at(i);
if (pair.variable() == var()) {
variable_feedback_slot_ = pair.slot();
return FeedbackVectorRequirements(0, 0);
}
ZoneHashMap::Entry* entry = cache->Get(var());
if (entry != NULL) {
variable_feedback_slot_ = FeedbackVectorICSlot(
static_cast<int>(reinterpret_cast<intptr_t>(entry->value)));
return FeedbackVectorRequirements(0, 0);
}
}
return FeedbackVectorRequirements(0, 1);
......
......@@ -152,25 +152,29 @@ class FeedbackVectorRequirements {
};
class VariableICSlotPair final {
class ICSlotCache {
public:
VariableICSlotPair(Variable* variable, FeedbackVectorICSlot slot)
: variable_(variable), slot_(slot) {}
VariableICSlotPair()
: variable_(NULL), slot_(FeedbackVectorICSlot::Invalid()) {}
explicit ICSlotCache(Zone* zone)
: zone_(zone),
hash_map_(HashMap::PointersMatch, ZoneHashMap::kDefaultHashMapCapacity,
ZoneAllocationPolicy(zone)) {}
Variable* variable() const { return variable_; }
FeedbackVectorICSlot slot() const { return slot_; }
void Put(Variable* variable, FeedbackVectorICSlot slot) {
ZoneHashMap::Entry* entry = hash_map_.LookupOrInsert(
variable, ComputePointerHash(variable), ZoneAllocationPolicy(zone_));
entry->value = reinterpret_cast<void*>(slot.ToInt());
}
ZoneHashMap::Entry* Get(Variable* variable) const {
return hash_map_.Lookup(variable, ComputePointerHash(variable));
}
private:
Variable* variable_;
FeedbackVectorICSlot slot_;
Zone* zone_;
ZoneHashMap hash_map_;
};
typedef List<VariableICSlotPair> ICSlotCache;
class AstProperties final BASE_EMBEDDED {
public:
enum Flag {
......
......@@ -43,7 +43,7 @@ class TemplateHashMapImpl {
// If an entry with matching key is found, returns that entry.
// Otherwise, NULL is returned.
Entry* Lookup(void* key, uint32_t hash);
Entry* Lookup(void* key, uint32_t hash) const;
// If an entry with matching key is found, returns that entry.
// If no matching entry is found, a new entry is inserted with
......@@ -90,7 +90,7 @@ class TemplateHashMapImpl {
uint32_t occupancy_;
Entry* map_end() const { return map_ + capacity_; }
Entry* Probe(void* key, uint32_t hash);
Entry* Probe(void* key, uint32_t hash) const;
void Initialize(uint32_t capacity, AllocationPolicy allocator);
void Resize(AllocationPolicy allocator);
};
......@@ -113,7 +113,7 @@ TemplateHashMapImpl<AllocationPolicy>::~TemplateHashMapImpl() {
template <class AllocationPolicy>
typename TemplateHashMapImpl<AllocationPolicy>::Entry*
TemplateHashMapImpl<AllocationPolicy>::Lookup(void* key, uint32_t hash) {
TemplateHashMapImpl<AllocationPolicy>::Lookup(void* key, uint32_t hash) const {
Entry* p = Probe(key, hash);
return p->key != NULL ? p : NULL;
}
......@@ -242,7 +242,7 @@ typename TemplateHashMapImpl<AllocationPolicy>::Entry*
template <class AllocationPolicy>
typename TemplateHashMapImpl<AllocationPolicy>::Entry*
TemplateHashMapImpl<AllocationPolicy>::Probe(void* key, uint32_t hash) {
TemplateHashMapImpl<AllocationPolicy>::Probe(void* key, uint32_t hash) const {
DCHECK(key != NULL);
DCHECK(base::bits::IsPowerOfTwo32(capacity_));
......
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