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 @@
#include "src/snapshot/natives.h"
#include "src/snapshot/serialize.h"
#include "src/snapshot/snapshot.h"
#include "src/type-feedback-vector.h"
#include "src/utils.h"
#include "src/v8.h"
#include "src/v8threads.h"
......@@ -478,8 +479,14 @@ const char* Heap::GetSpaceName(int idx) {
}
void Heap::ClearAllICsByKind(Code::Kind kind) {
// TODO(mvstanton): Do not iterate the heap.
void Heap::ClearAllKeyedStoreICs() {
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());
for (Object* object = it.Next(); object != NULL; object = it.Next()) {
......@@ -487,7 +494,7 @@ void Heap::ClearAllICsByKind(Code::Kind kind) {
Code::Kind current_kind = code->kind();
if (current_kind == Code::FUNCTION ||
current_kind == Code::OPTIMIZED_FUNCTION) {
code->ClearInlineCaches(kind);
code->ClearInlineCaches(Code::KEYED_STORE_IC);
}
}
}
......
......@@ -817,8 +817,8 @@ class Heap {
// Clear the Instanceof cache (used when a prototype changes).
inline void ClearInstanceofCache();
// Iterates the whole code space to clear all ICs of the given kind.
void ClearAllICsByKind(Code::Kind kind);
// Iterates the whole code space to clear all keyed store ICs.
void ClearAllKeyedStoreICs();
// FreeSpace objects have a null map after deserialization. Update the map.
void RepairFreeListsAfterDeserialization();
......
......@@ -575,10 +575,17 @@ void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) { // NOLINT
KeyedLoadICNexus nexus(this, slot);
os << " KEYED_LOAD_IC "
<< Code::ICState2String(nexus.StateFromFeedback());
} else {
DCHECK(kind == Code::CALL_IC);
} else if (kind == Code::CALL_IC) {
CallICNexus nexus(this, slot);
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));
......
......@@ -4765,7 +4765,7 @@ void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) {
dictionary->set_requires_slow_elements();
// TODO(verwaest): Remove this hack.
if (map()->is_prototype_map()) {
GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
GetHeap()->ClearAllKeyedStoreICs();
}
}
......@@ -12108,7 +12108,7 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
// If the prototype chain didn't previously have element callbacks, then
// KeyedStoreICs need to be cleared to ensure any that involve this
// map go generic.
object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
object->GetHeap()->ClearAllKeyedStoreICs();
}
heap->ClearInstanceofCache();
......@@ -14522,7 +14522,7 @@ void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key,
if (key > kRequiresSlowElementsLimit) {
if (used_as_prototype) {
// TODO(verwaest): Remove this hack.
GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
GetHeap()->ClearAllKeyedStoreICs();
}
set_requires_slow_elements();
return;
......
......@@ -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
Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) {
return Handle<TypeFeedbackVector>::cast(isolate->factory()->dummy_vector());
......
......@@ -213,6 +213,9 @@ class TypeFeedbackVector : public FixedArray {
ClearICSlotsImpl(shared, false);
}
static void ClearAllKeyedStoreICs(Isolate* isolate);
void ClearKeyedStoreICs(SharedFunctionInfo* shared);
// The object that indicates an uninitialized cache.
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