Commit 7db48046 authored by mvstanton's avatar mvstanton Committed by Commit bot

Vector ICs: Stop iterating the heap to clear keyed store ics.

When vector based stores are on, we don't need to do this anymore.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#30401}
parent 1c6139de
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "src/snapshot/natives.h" #include "src/snapshot/natives.h"
#include "src/snapshot/serialize.h" #include "src/snapshot/serialize.h"
#include "src/snapshot/snapshot.h" #include "src/snapshot/snapshot.h"
#include "src/type-feedback-vector.h"
#include "src/utils.h" #include "src/utils.h"
#include "src/v8.h" #include "src/v8.h"
#include "src/v8threads.h" #include "src/v8threads.h"
...@@ -478,8 +479,14 @@ const char* Heap::GetSpaceName(int idx) { ...@@ -478,8 +479,14 @@ const char* Heap::GetSpaceName(int idx) {
} }
void Heap::ClearAllICsByKind(Code::Kind kind) { void Heap::ClearAllKeyedStoreICs() {
// TODO(mvstanton): Do not iterate the heap. if (FLAG_vector_stores) {
TypeFeedbackVector::ClearAllKeyedStoreICs(isolate_);
return;
}
// TODO(mvstanton): Remove this function when FLAG_vector_stores is turned on
// permanently, and divert all callers to KeyedStoreIC::ClearAllKeyedStoreICs.
HeapObjectIterator it(code_space()); HeapObjectIterator it(code_space());
for (Object* object = it.Next(); object != NULL; object = it.Next()) { for (Object* object = it.Next(); object != NULL; object = it.Next()) {
...@@ -487,7 +494,7 @@ void Heap::ClearAllICsByKind(Code::Kind kind) { ...@@ -487,7 +494,7 @@ void Heap::ClearAllICsByKind(Code::Kind kind) {
Code::Kind current_kind = code->kind(); Code::Kind current_kind = code->kind();
if (current_kind == Code::FUNCTION || if (current_kind == Code::FUNCTION ||
current_kind == Code::OPTIMIZED_FUNCTION) { current_kind == Code::OPTIMIZED_FUNCTION) {
code->ClearInlineCaches(kind); code->ClearInlineCaches(Code::KEYED_STORE_IC);
} }
} }
} }
......
...@@ -817,8 +817,8 @@ class Heap { ...@@ -817,8 +817,8 @@ class Heap {
// Clear the Instanceof cache (used when a prototype changes). // Clear the Instanceof cache (used when a prototype changes).
inline void ClearInstanceofCache(); inline void ClearInstanceofCache();
// Iterates the whole code space to clear all ICs of the given kind. // Iterates the whole code space to clear all keyed store ICs.
void ClearAllICsByKind(Code::Kind kind); void ClearAllKeyedStoreICs();
// FreeSpace objects have a null map after deserialization. Update the map. // FreeSpace objects have a null map after deserialization. Update the map.
void RepairFreeListsAfterDeserialization(); void RepairFreeListsAfterDeserialization();
......
...@@ -575,10 +575,17 @@ void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) { // NOLINT ...@@ -575,10 +575,17 @@ void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) { // NOLINT
KeyedLoadICNexus nexus(this, slot); KeyedLoadICNexus nexus(this, slot);
os << " KEYED_LOAD_IC " os << " KEYED_LOAD_IC "
<< Code::ICState2String(nexus.StateFromFeedback()); << Code::ICState2String(nexus.StateFromFeedback());
} else { } else if (kind == Code::CALL_IC) {
DCHECK(kind == Code::CALL_IC);
CallICNexus nexus(this, slot); CallICNexus nexus(this, slot);
os << " CALL_IC " << Code::ICState2String(nexus.StateFromFeedback()); os << " CALL_IC " << Code::ICState2String(nexus.StateFromFeedback());
} else if (kind == Code::STORE_IC) {
StoreICNexus nexus(this, slot);
os << " STORE_IC " << Code::ICState2String(nexus.StateFromFeedback());
} else {
DCHECK(kind == Code::KEYED_STORE_IC);
KeyedStoreICNexus nexus(this, slot);
os << " KEYED_STORE_IC "
<< Code::ICState2String(nexus.StateFromFeedback());
} }
os << "\n [" << GetIndex(slot) << "]: " << Brief(Get(slot)); os << "\n [" << GetIndex(slot) << "]: " << Brief(Get(slot));
......
...@@ -4765,7 +4765,7 @@ void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) { ...@@ -4765,7 +4765,7 @@ void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) {
dictionary->set_requires_slow_elements(); dictionary->set_requires_slow_elements();
// TODO(verwaest): Remove this hack. // TODO(verwaest): Remove this hack.
if (map()->is_prototype_map()) { if (map()->is_prototype_map()) {
GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); GetHeap()->ClearAllKeyedStoreICs();
} }
} }
...@@ -12108,7 +12108,7 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object, ...@@ -12108,7 +12108,7 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
// If the prototype chain didn't previously have element callbacks, then // If the prototype chain didn't previously have element callbacks, then
// KeyedStoreICs need to be cleared to ensure any that involve this // KeyedStoreICs need to be cleared to ensure any that involve this
// map go generic. // map go generic.
object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); object->GetHeap()->ClearAllKeyedStoreICs();
} }
heap->ClearInstanceofCache(); heap->ClearInstanceofCache();
...@@ -14522,7 +14522,7 @@ void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key, ...@@ -14522,7 +14522,7 @@ void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key,
if (key > kRequiresSlowElementsLimit) { if (key > kRequiresSlowElementsLimit) {
if (used_as_prototype) { if (used_as_prototype) {
// TODO(verwaest): Remove this hack. // TODO(verwaest): Remove this hack.
GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); GetHeap()->ClearAllKeyedStoreICs();
} }
set_requires_slow_elements(); set_requires_slow_elements();
return; return;
......
...@@ -223,6 +223,40 @@ void TypeFeedbackVector::ClearICSlotsImpl(SharedFunctionInfo* shared, ...@@ -223,6 +223,40 @@ void TypeFeedbackVector::ClearICSlotsImpl(SharedFunctionInfo* shared,
} }
// static
void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) {
DCHECK(FLAG_vector_stores);
SharedFunctionInfo::Iterator iterator(isolate);
SharedFunctionInfo* shared;
while ((shared = iterator.Next())) {
TypeFeedbackVector* vector = shared->feedback_vector();
vector->ClearKeyedStoreICs(shared);
}
}
void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) {
Heap* heap = GetIsolate()->heap();
int slots = ICSlots();
Code* host = shared->code();
Object* uninitialized_sentinel =
TypeFeedbackVector::RawUninitializedSentinel(heap);
for (int i = 0; i < slots; i++) {
FeedbackVectorICSlot slot(i);
Object* obj = Get(slot);
if (obj != uninitialized_sentinel) {
Code::Kind kind = GetKind(slot);
if (kind == Code::KEYED_STORE_IC) {
DCHECK(FLAG_vector_stores);
KeyedStoreICNexus nexus(this, slot);
nexus.Clear(host);
}
}
}
}
// static // static
Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) { Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) {
return Handle<TypeFeedbackVector>::cast(isolate->factory()->dummy_vector()); return Handle<TypeFeedbackVector>::cast(isolate->factory()->dummy_vector());
......
...@@ -213,6 +213,9 @@ class TypeFeedbackVector : public FixedArray { ...@@ -213,6 +213,9 @@ class TypeFeedbackVector : public FixedArray {
ClearICSlotsImpl(shared, false); ClearICSlotsImpl(shared, false);
} }
static void ClearAllKeyedStoreICs(Isolate* isolate);
void ClearKeyedStoreICs(SharedFunctionInfo* shared);
// The object that indicates an uninitialized cache. // The object that indicates an uninitialized cache.
static inline Handle<Object> UninitializedSentinel(Isolate* isolate); static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
......
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