Commit 6527825f authored by mvstanton's avatar mvstanton Committed by Commit bot

Vector ICs: Changes to the IC system to support vector-based stores.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#29371}
parent d16c61bf
......@@ -98,10 +98,11 @@ void IC::SetTargetAtAddress(Address address, Code* target,
DCHECK(target->is_inline_cache_stub() || target->is_compare_ic_stub());
// Don't use this for load_ics when --vector-ics is turned on.
DCHECK(!target->is_inline_cache_stub() ||
(target->kind() != Code::LOAD_IC &&
target->kind() != Code::KEYED_LOAD_IC));
target->kind() != Code::KEYED_LOAD_IC &&
(!FLAG_vector_stores || (target->kind() != Code::STORE_IC &&
target->kind() != Code::KEYED_STORE_IC))));
Heap* heap = target->GetHeap();
Code* old_target = GetTargetAtAddress(address, constant_pool);
......
This diff is collapsed.
......@@ -114,7 +114,9 @@ class IC {
static bool ICUseVector(Code::Kind kind) {
return kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC ||
kind == Code::CALL_IC;
kind == Code::CALL_IC ||
(FLAG_vector_stores &&
(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC));
}
protected:
......@@ -497,7 +499,8 @@ class StoreIC : public IC {
return StoreICState(flag).GetExtraICState();
}
StoreIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
StoreIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
: IC(depth, isolate, nexus) {
DCHECK(IsStoreStub());
}
......@@ -531,6 +534,8 @@ class StoreIC : public IC {
bool LookupForWrite(LookupIterator* it, Handle<Object> value,
JSReceiver::StoreFromKeyed store_mode);
static void Clear(Isolate* isolate, Code* host, StoreICNexus* nexus);
protected:
// Stub accessors.
Handle<Code> megamorphic_stub() override;
......@@ -594,7 +599,9 @@ class KeyedStoreIC : public StoreIC {
return IcCheckTypeField::decode(extra_state);
}
KeyedStoreIC(FrameDepth depth, Isolate* isolate) : StoreIC(depth, isolate) {
KeyedStoreIC(FrameDepth depth, Isolate* isolate,
KeyedStoreICNexus* nexus = NULL)
: StoreIC(depth, isolate, nexus) {
DCHECK(target()->is_keyed_store_stub());
}
......@@ -619,6 +626,8 @@ class KeyedStoreIC : public StoreIC {
static Handle<Code> initialize_stub_in_optimized_code(
Isolate* isolate, LanguageMode language_mode, State initialization_state);
static void Clear(Isolate* isolate, Code* host, KeyedStoreICNexus* nexus);
protected:
virtual Handle<Code> pre_monomorphic_stub() const {
return pre_monomorphic_stub(isolate(), language_mode());
......
......@@ -211,9 +211,15 @@ void TypeFeedbackVector::ClearICSlotsImpl(SharedFunctionInfo* shared,
} else if (kind == Code::KEYED_LOAD_IC) {
KeyedLoadICNexus nexus(this, slot);
nexus.Clear(host);
} else if (kind == Code::STORE_IC) {
DCHECK(FLAG_vector_stores);
StoreICNexus nexus(this, slot);
nexus.Clear(host);
} else if (kind == Code::KEYED_STORE_IC) {
DCHECK(FLAG_vector_stores);
KeyedStoreICNexus nexus(this, slot);
nexus.Clear(host);
}
// TODO(mvstanton): Handle clearing of store ics when FLAG_vector_stores
// is true.
}
}
}
......@@ -258,6 +264,31 @@ void FeedbackNexus::InstallHandlers(Handle<FixedArray> array,
}
void FeedbackNexus::ConfigureUninitialized() {
SetFeedback(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
}
void FeedbackNexus::ConfigurePremonomorphic() {
SetFeedback(*TypeFeedbackVector::PremonomorphicSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
}
void FeedbackNexus::ConfigureMegamorphic() {
Isolate* isolate = GetIsolate();
SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(isolate),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate),
SKIP_WRITE_BARRIER);
}
InlineCacheState LoadICNexus::StateFromFeedback() const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
......@@ -308,6 +339,56 @@ InlineCacheState KeyedLoadICNexus::StateFromFeedback() const {
}
InlineCacheState StoreICNexus::StateFromFeedback() const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) {
return UNINITIALIZED;
} else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) {
return MEGAMORPHIC;
} else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) {
return PREMONOMORPHIC;
} else if (feedback->IsFixedArray()) {
// Determine state purely by our structure, don't check if the maps are
// cleared.
return POLYMORPHIC;
} else if (feedback->IsWeakCell()) {
// Don't check if the map is cleared.
return MONOMORPHIC;
}
return UNINITIALIZED;
}
InlineCacheState KeyedStoreICNexus::StateFromFeedback() const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) {
return UNINITIALIZED;
} else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) {
return PREMONOMORPHIC;
} else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) {
return MEGAMORPHIC;
} else if (feedback->IsFixedArray()) {
// Determine state purely by our structure, don't check if the maps are
// cleared.
return POLYMORPHIC;
} else if (feedback->IsWeakCell()) {
// Don't check if the map is cleared.
return MONOMORPHIC;
} else if (feedback->IsName()) {
Object* extra = GetFeedbackExtra();
FixedArray* extra_array = FixedArray::cast(extra);
return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC;
}
return UNINITIALIZED;
}
InlineCacheState CallICNexus::StateFromFeedback() const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
......@@ -339,14 +420,6 @@ int CallICNexus::ExtractCallCount() {
void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); }
void CallICNexus::ConfigureGeneric() {
SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
}
void CallICNexus::ConfigureMonomorphicArray() {
Object* feedback = GetFeedback();
if (!feedback->IsAllocationSite()) {
......@@ -358,14 +431,6 @@ void CallICNexus::ConfigureMonomorphicArray() {
}
void CallICNexus::ConfigureUninitialized() {
SetFeedback(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
}
void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) {
Handle<WeakCell> new_cell = GetIsolate()->factory()->NewWeakCell(function);
SetFeedback(*new_cell);
......@@ -373,51 +438,41 @@ void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) {
}
void KeyedLoadICNexus::ConfigureMegamorphic() {
Isolate* isolate = GetIsolate();
SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(isolate),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate),
SKIP_WRITE_BARRIER);
}
void LoadICNexus::ConfigureMegamorphic() {
SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
}
void LoadICNexus::ConfigurePremonomorphic() {
SetFeedback(*TypeFeedbackVector::PremonomorphicSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map,
Handle<Code> handler) {
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
SetFeedback(*cell);
SetFeedbackExtra(*handler);
}
void KeyedLoadICNexus::ConfigurePremonomorphic() {
Isolate* isolate = GetIsolate();
SetFeedback(*TypeFeedbackVector::PremonomorphicSentinel(isolate),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate),
SKIP_WRITE_BARRIER);
void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
Handle<Map> receiver_map,
Handle<Code> handler) {
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
if (name.is_null()) {
SetFeedback(*cell);
SetFeedbackExtra(*handler);
} else {
SetFeedback(*name);
Handle<FixedArray> array = EnsureExtraArrayOfSize(2);
array->set(0, *cell);
array->set(1, *handler);
}
}
void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map,
Handle<Code> handler) {
void StoreICNexus::ConfigureMonomorphic(Handle<Map> receiver_map,
Handle<Code> handler) {
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
SetFeedback(*cell);
SetFeedbackExtra(*handler);
}
void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
Handle<Map> receiver_map,
Handle<Code> handler) {
void KeyedStoreICNexus::ConfigureMonomorphic(Handle<Name> name,
Handle<Map> receiver_map,
Handle<Code> handler) {
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
if (name.is_null()) {
SetFeedback(*cell);
......@@ -461,6 +516,36 @@ void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name,
}
void StoreICNexus::ConfigurePolymorphic(MapHandleList* maps,
CodeHandleList* handlers) {
Isolate* isolate = GetIsolate();
int receiver_count = maps->length();
Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2);
InstallHandlers(array, maps, handlers);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate),
SKIP_WRITE_BARRIER);
}
void KeyedStoreICNexus::ConfigurePolymorphic(Handle<Name> name,
MapHandleList* maps,
CodeHandleList* handlers) {
int receiver_count = maps->length();
DCHECK(receiver_count > 1);
Handle<FixedArray> array;
if (name.is_null()) {
array = EnsureArrayOfSize(receiver_count * 2);
SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
} else {
SetFeedback(*name);
array = EnsureExtraArrayOfSize(receiver_count * 2);
}
InstallHandlers(array, maps, handlers);
}
int FeedbackNexus::ExtractMaps(MapHandleList* maps) const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
......@@ -580,5 +665,24 @@ Name* KeyedLoadICNexus::FindFirstName() const {
}
return NULL;
}
Name* KeyedStoreICNexus::FindFirstName() const {
Object* feedback = GetFeedback();
if (feedback->IsString()) {
return Name::cast(feedback);
}
return NULL;
}
void StoreICNexus::Clear(Code* host) {
StoreIC::Clear(GetIsolate(), host, this);
}
void KeyedStoreICNexus::Clear(Code* host) {
KeyedStoreIC::Clear(GetIsolate(), host, this);
}
} // namespace internal
} // namespace v8
......@@ -294,6 +294,10 @@ class FeedbackNexus {
virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const;
virtual Name* FindFirstName() const { return NULL; }
virtual void ConfigureUninitialized();
virtual void ConfigurePremonomorphic();
virtual void ConfigureMegamorphic();
Object* GetFeedback() const { return vector()->Get(slot()); }
Object* GetFeedbackExtra() const {
DCHECK(TypeFeedbackVector::elements_per_ic_slot() > 1);
......@@ -349,8 +353,6 @@ class CallICNexus : public FeedbackNexus {
void Clear(Code* host);
void ConfigureUninitialized();
void ConfigureGeneric();
void ConfigureMonomorphicArray();
void ConfigureMonomorphic(Handle<JSFunction> function);
......@@ -363,8 +365,7 @@ class CallICNexus : public FeedbackNexus {
MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const override {
return MaybeHandle<Code>();
}
virtual bool FindHandlers(CodeHandleList* code_list,
int length = -1) const override {
bool FindHandlers(CodeHandleList* code_list, int length = -1) const override {
return length == 0;
}
......@@ -385,8 +386,6 @@ class LoadICNexus : public FeedbackNexus {
void Clear(Code* host);
void ConfigureMegamorphic();
void ConfigurePremonomorphic();
void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
......@@ -408,8 +407,53 @@ class KeyedLoadICNexus : public FeedbackNexus {
void Clear(Code* host);
void ConfigureMegamorphic();
void ConfigurePremonomorphic();
// name can be a null handle for element loads.
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
Handle<Code> handler);
// name can be null.
void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
CodeHandleList* handlers);
InlineCacheState StateFromFeedback() const override;
Name* FindFirstName() const override;
};
class StoreICNexus : public FeedbackNexus {
public:
StoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK(vector->GetKind(slot) == Code::STORE_IC);
}
StoreICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK(vector->GetKind(slot) == Code::STORE_IC);
}
void Clear(Code* host);
void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
InlineCacheState StateFromFeedback() const override;
};
class KeyedStoreICNexus : public FeedbackNexus {
public:
KeyedStoreICNexus(Handle<TypeFeedbackVector> vector,
FeedbackVectorICSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK(vector->GetKind(slot) == Code::KEYED_STORE_IC);
}
KeyedStoreICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK(vector->GetKind(slot) == Code::KEYED_STORE_IC);
}
void Clear(Code* host);
// name can be a null handle for element loads.
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
Handle<Code> handler);
......
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