[ic] Cleanup nexus configuring now that all property access ICs are uniform

BUG=v8:5561

Change-Id: I26330670c526390c05e652b3862f0ef7244f7b19
Reviewed-on: https://chromium-review.googlesource.com/456288
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43991}
This commit is contained in:
Toon Verwaest 2017-03-21 17:13:00 +01:00 committed by Commit Bot
parent 503103ebcf
commit 825836188d
7 changed files with 39 additions and 332 deletions

View File

@ -422,18 +422,6 @@ Handle<FixedArray> FeedbackNexus::EnsureExtraArrayOfSize(int length) {
return Handle<FixedArray>::cast(feedback_extra);
}
void FeedbackNexus::InstallHandlers(Handle<FixedArray> array,
MapHandleList* maps,
List<Handle<Object>>* handlers) {
int receiver_count = maps->length();
for (int current = 0; current < receiver_count; ++current) {
Handle<Map> map = maps->at(current);
Handle<WeakCell> cell = Map::WeakCellForMap(map);
array->set(current * 2, *cell);
array->set(current * 2 + 1, *handlers->at(current));
}
}
void FeedbackNexus::ConfigureUninitialized() {
SetFeedback(*FeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
@ -448,27 +436,7 @@ void FeedbackNexus::ConfigurePremonomorphic() {
SKIP_WRITE_BARRIER);
}
void FeedbackNexus::ConfigureMegamorphic() {
// Keyed ICs must use ConfigureMegamorphicKeyed.
DCHECK(!vector()->IsKeyedLoadIC(slot()));
DCHECK(!vector()->IsKeyedStoreIC(slot()));
Isolate* isolate = GetIsolate();
SetFeedback(*FeedbackVector::MegamorphicSentinel(isolate),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
SKIP_WRITE_BARRIER);
}
void KeyedLoadICNexus::ConfigureMegamorphicKeyed(IcCheckType property_type) {
Isolate* isolate = GetIsolate();
SetFeedback(*FeedbackVector::MegamorphicSentinel(isolate),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(Smi::FromInt(static_cast<int>(property_type)),
SKIP_WRITE_BARRIER);
}
void KeyedStoreICNexus::ConfigureMegamorphicKeyed(IcCheckType property_type) {
void FeedbackNexus::ConfigureMegamorphic(IcCheckType property_type) {
Isolate* isolate = GetIsolate();
SetFeedback(*FeedbackVector::MegamorphicSentinel(isolate),
SKIP_WRITE_BARRIER);
@ -625,43 +593,6 @@ void CallICNexus::ConfigureUninitialized() {
SetFeedbackExtra(Smi::kZero, SKIP_WRITE_BARRIER);
}
void CallICNexus::ConfigureMonomorphicArray() {
Object* feedback = GetFeedback();
if (!feedback->IsAllocationSite()) {
Handle<AllocationSite> new_site =
GetIsolate()->factory()->NewAllocationSite();
SetFeedback(*new_site);
}
SetFeedbackExtra(Smi::FromInt(1), SKIP_WRITE_BARRIER);
}
void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) {
Handle<WeakCell> new_cell = GetIsolate()->factory()->NewWeakCell(function);
SetFeedback(*new_cell);
SetFeedbackExtra(Smi::FromInt(1), SKIP_WRITE_BARRIER);
}
void CallICNexus::ConfigureMegamorphic() {
SetFeedback(*FeedbackVector::MegamorphicSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
Smi* count = Smi::cast(GetFeedbackExtra());
int new_count = count->value() + 1;
SetFeedbackExtra(Smi::FromInt(new_count), SKIP_WRITE_BARRIER);
}
void CallICNexus::ConfigureMegamorphic(int call_count) {
SetFeedback(*FeedbackVector::MegamorphicSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
SetFeedbackExtra(Smi::FromInt(call_count), SKIP_WRITE_BARRIER);
}
void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map,
Handle<Object> handler) {
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
SetFeedback(*cell);
SetFeedbackExtra(*handler);
}
void LoadGlobalICNexus::ConfigureUninitialized() {
Isolate* isolate = GetIsolate();
SetFeedback(isolate->heap()->empty_weak_cell(), SKIP_WRITE_BARRIER);
@ -681,9 +612,9 @@ void LoadGlobalICNexus::ConfigureHandlerMode(Handle<Object> handler) {
SetFeedbackExtra(*handler);
}
void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
Handle<Map> receiver_map,
Handle<Object> handler) {
void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
Handle<Map> receiver_map,
Handle<Object> handler) {
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
if (name.is_null()) {
SetFeedback(*cell);
@ -696,41 +627,8 @@ void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
}
}
void StoreICNexus::ConfigureMonomorphic(Handle<Map> receiver_map,
Handle<Object> handler) {
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
SetFeedback(*cell);
SetFeedbackExtra(*handler);
}
void KeyedStoreICNexus::ConfigureMonomorphic(Handle<Name> name,
Handle<Map> receiver_map,
Handle<Object> handler) {
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
if (name.is_null()) {
SetFeedback(*cell);
SetFeedbackExtra(*handler);
} else {
Handle<FixedArray> array = EnsureExtraArrayOfSize(2);
SetFeedback(*name);
array->set(0, *cell);
array->set(1, *handler);
}
}
void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps,
List<Handle<Object>>* handlers) {
Isolate* isolate = GetIsolate();
int receiver_count = maps->length();
Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2);
InstallHandlers(array, maps, handlers);
SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
SKIP_WRITE_BARRIER);
}
void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name,
MapHandleList* maps,
List<Handle<Object>>* handlers) {
void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
List<Handle<Object>>* handlers) {
int receiver_count = maps->length();
DCHECK(receiver_count > 1);
Handle<FixedArray> array;
@ -743,46 +641,12 @@ void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name,
SetFeedback(*name);
}
InstallHandlers(array, maps, handlers);
}
void StoreICNexus::ConfigurePolymorphic(MapHandleList* maps,
List<Handle<Object>>* handlers) {
Isolate* isolate = GetIsolate();
int receiver_count = maps->length();
Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2);
InstallHandlers(array, maps, handlers);
SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
SKIP_WRITE_BARRIER);
}
void KeyedStoreICNexus::ConfigurePolymorphic(Handle<Name> name,
MapHandleList* maps,
List<Handle<Object>>* handlers) {
int receiver_count = maps->length();
DCHECK(receiver_count > 1);
Handle<FixedArray> array;
if (name.is_null()) {
array = EnsureArrayOfSize(receiver_count * 2);
SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
} else {
array = EnsureExtraArrayOfSize(receiver_count * 2);
SetFeedback(*name);
for (int current = 0; current < receiver_count; ++current) {
Handle<Map> map = maps->at(current);
Handle<WeakCell> cell = Map::WeakCellForMap(map);
array->set(current * 2, *cell);
array->set(current * 2 + 1, *handlers->at(current));
}
InstallHandlers(array, maps, handlers);
}
void KeyedStoreICNexus::ConfigurePolymorphic(MapHandleList* maps,
List<Handle<Object>>* handlers) {
int receiver_count = maps->length();
DCHECK(receiver_count > 1);
Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2);
SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(GetIsolate()),
SKIP_WRITE_BARRIER);
InstallHandlers(array, maps, handlers);
}
int FeedbackNexus::ExtractMaps(MapHandleList* maps) const {

View File

@ -474,14 +474,20 @@ class FeedbackNexus {
virtual void Clear() { ConfigureUninitialized(); }
virtual void ConfigureUninitialized();
virtual void ConfigurePremonomorphic();
virtual void ConfigureMegamorphic();
void ConfigurePremonomorphic();
void ConfigureMegamorphic(IcCheckType property_type);
inline Object* GetFeedback() const;
inline Object* GetFeedbackExtra() const;
inline Isolate* GetIsolate() const;
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
Handle<Object> handler);
void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
List<Handle<Object>>* handlers);
protected:
inline void SetFeedback(Object* feedback,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
@ -490,8 +496,6 @@ class FeedbackNexus {
Handle<FixedArray> EnsureArrayOfSize(int length);
Handle<FixedArray> EnsureExtraArrayOfSize(int length);
void InstallHandlers(Handle<FixedArray> array, MapHandleList* maps,
List<Handle<Object>>* handlers);
private:
// The reason for having a vector handle and a raw pointer is that we can and
@ -514,11 +518,7 @@ class CallICNexus final : public FeedbackNexus {
DCHECK(vector->IsCallIC(slot));
}
void ConfigureUninitialized() override;
void ConfigureMonomorphicArray();
void ConfigureMonomorphic(Handle<JSFunction> function);
void ConfigureMegamorphic() final;
void ConfigureMegamorphic(int call_count);
void ConfigureUninitialized() final;
InlineCacheState StateFromFeedback() const final;
@ -554,11 +554,6 @@ class LoadICNexus : public FeedbackNexus {
void Clear() override { ConfigurePremonomorphic(); }
void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Object> handler);
void ConfigurePolymorphic(MapHandleList* maps,
List<Handle<Object>>* handlers);
InlineCacheState StateFromFeedback() const override;
};
@ -585,8 +580,6 @@ class LoadGlobalICNexus : public FeedbackNexus {
return length == 0;
}
void ConfigureMegamorphic() override { UNREACHABLE(); }
void ConfigureUninitialized() override;
void ConfigurePropertyCellMode(Handle<PropertyCell> cell);
void ConfigureHandlerMode(Handle<Object> handler);
@ -607,15 +600,6 @@ class KeyedLoadICNexus : public FeedbackNexus {
void Clear() override { ConfigurePremonomorphic(); }
// name can be a null handle for element loads.
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
Handle<Object> handler);
// name can be null.
void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
List<Handle<Object>>* handlers);
void ConfigureMegamorphicKeyed(IcCheckType property_type);
IcCheckType GetKeyType() const;
InlineCacheState StateFromFeedback() const override;
Name* FindFirstName() const override;
@ -634,11 +618,6 @@ class StoreICNexus : public FeedbackNexus {
void Clear() override { ConfigurePremonomorphic(); }
void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Object> handler);
void ConfigurePolymorphic(MapHandleList* maps,
List<Handle<Object>>* handlers);
InlineCacheState StateFromFeedback() const override;
};
@ -659,16 +638,6 @@ class KeyedStoreICNexus : public FeedbackNexus {
void Clear() override { ConfigurePremonomorphic(); }
// name can be a null handle for element loads.
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
Handle<Object> handler);
// name can be null.
void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
List<Handle<Object>>* handlers);
void ConfigurePolymorphic(MapHandleList* maps,
List<Handle<Object>>* handlers);
void ConfigureMegamorphicKeyed(IcCheckType property_type);
KeyedAccessStoreMode GetKeyedAccessStoreMode() const;
IcCheckType GetKeyType() const;

View File

@ -126,35 +126,6 @@ void AccessorAssembler::HandlePolymorphicCase(Node* receiver_map,
Goto(if_miss);
}
void AccessorAssembler::HandleKeyedStorePolymorphicCase(Node* receiver_map,
Node* feedback,
Label* if_handler,
Variable* var_handler,
Label* if_miss) {
DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
const int kEntrySize = 2;
Node* init = IntPtrConstant(0);
Node* length = LoadAndUntagFixedArrayBaseLength(feedback);
BuildFastLoop(init, length,
[=](Node* index) {
Node* cached_map =
LoadWeakCellValue(LoadFixedArrayElement(feedback, index));
Label next_entry(this);
GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry);
var_handler->Bind(
LoadFixedArrayElement(feedback, index, kPointerSize));
Goto(if_handler);
Bind(&next_entry);
},
kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
// The loop falls through if no handler was found.
Goto(if_miss);
}
void AccessorAssembler::HandleLoadICHandlerCase(
const LoadICParameters* p, Node* handler, Label* miss,
ExitPoint* exit_point, ElementSupport support_elements) {
@ -775,6 +746,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
}
Node* smi_handler = smi_or_code;
CSA_ASSERT(this, TaggedIsSmi(smi_handler));
Node* handler_word = SmiUntag(smi_handler);
Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word);
@ -2178,8 +2150,8 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p,
GotoIfNot(
WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
&try_megamorphic);
HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler,
&var_handler, &miss);
HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler,
&miss, 2);
}
Bind(&try_megamorphic);

View File

@ -124,9 +124,6 @@ class AccessorAssembler : public CodeStubAssembler {
void HandlePolymorphicCase(Node* receiver_map, Node* feedback,
Label* if_handler, Variable* var_handler,
Label* if_miss, int min_feedback_capacity);
void HandleKeyedStorePolymorphicCase(Node* receiver_map, Node* feedback,
Label* if_handler, Variable* var_handler,
Label* if_miss);
// LoadIC implementation.

View File

@ -516,16 +516,8 @@ void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
if (new_state == PREMONOMORPHIC) {
nexus()->ConfigurePremonomorphic();
} else if (new_state == MEGAMORPHIC) {
if (IsLoadIC() || IsStoreIC() || IsStoreOwnIC()) {
nexus()->ConfigureMegamorphic();
} else if (IsKeyedLoadIC()) {
KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
} else {
DCHECK(IsKeyedStoreIC());
KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
}
DCHECK_IMPLIES(!is_keyed(), key->IsName());
nexus()->ConfigureMegamorphic(key->IsName() ? PROPERTY : ELEMENT);
} else {
UNREACHABLE();
}
@ -536,49 +528,13 @@ void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
Handle<Object> handler) {
switch (kind_) {
case FeedbackSlotKind::kLoadProperty: {
LoadICNexus* nexus = casted_nexus<LoadICNexus>();
nexus->ConfigureMonomorphic(map, handler);
break;
}
case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
case FeedbackSlotKind::kLoadGlobalInsideTypeof: {
LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>();
nexus->ConfigureHandlerMode(handler);
break;
}
case FeedbackSlotKind::kLoadKeyed: {
KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
nexus->ConfigureMonomorphic(name, map, handler);
break;
}
case FeedbackSlotKind::kStoreNamedSloppy:
case FeedbackSlotKind::kStoreNamedStrict:
case FeedbackSlotKind::kStoreOwnNamed: {
StoreICNexus* nexus = casted_nexus<StoreICNexus>();
nexus->ConfigureMonomorphic(map, handler);
break;
}
case FeedbackSlotKind::kStoreKeyedSloppy:
case FeedbackSlotKind::kStoreKeyedStrict: {
KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
nexus->ConfigureMonomorphic(name, map, handler);
break;
}
case FeedbackSlotKind::kCall:
case FeedbackSlotKind::kBinaryOp:
case FeedbackSlotKind::kCompareOp:
case FeedbackSlotKind::kToBoolean:
case FeedbackSlotKind::kCreateClosure:
case FeedbackSlotKind::kLiteral:
case FeedbackSlotKind::kGeneral:
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
case FeedbackSlotKind::kTypeProfile:
case FeedbackSlotKind::kInvalid:
case FeedbackSlotKind::kKindsNumber:
UNREACHABLE();
break;
if (IsLoadGlobalIC()) {
LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>();
nexus->ConfigureHandlerMode(handler);
} else {
// Non-keyed ICs don't track the name explicitly.
if (!is_keyed()) name = Handle<Name>::null();
nexus()->ConfigureMonomorphic(name, map, handler);
}
vector_set_ = true;
@ -587,62 +543,15 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
List<Handle<Object>>* handlers) {
switch (kind_) {
case FeedbackSlotKind::kLoadProperty: {
LoadICNexus* nexus = casted_nexus<LoadICNexus>();
nexus->ConfigurePolymorphic(maps, handlers);
break;
}
case FeedbackSlotKind::kLoadKeyed: {
KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
nexus->ConfigurePolymorphic(name, maps, handlers);
break;
}
case FeedbackSlotKind::kStoreNamedSloppy:
case FeedbackSlotKind::kStoreNamedStrict:
case FeedbackSlotKind::kStoreOwnNamed: {
StoreICNexus* nexus = casted_nexus<StoreICNexus>();
nexus->ConfigurePolymorphic(maps, handlers);
break;
}
case FeedbackSlotKind::kStoreKeyedSloppy:
case FeedbackSlotKind::kStoreKeyedStrict: {
KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
nexus->ConfigurePolymorphic(name, maps, handlers);
break;
}
case FeedbackSlotKind::kCall:
case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
case FeedbackSlotKind::kLoadGlobalInsideTypeof:
case FeedbackSlotKind::kBinaryOp:
case FeedbackSlotKind::kCompareOp:
case FeedbackSlotKind::kToBoolean:
case FeedbackSlotKind::kCreateClosure:
case FeedbackSlotKind::kLiteral:
case FeedbackSlotKind::kGeneral:
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
case FeedbackSlotKind::kTypeProfile:
case FeedbackSlotKind::kInvalid:
case FeedbackSlotKind::kKindsNumber:
UNREACHABLE();
break;
}
DCHECK(!IsLoadGlobalIC());
// Non-keyed ICs don't track the name explicitly.
if (!is_keyed()) name = Handle<Name>::null();
nexus()->ConfigurePolymorphic(name, maps, handlers);
vector_set_ = true;
OnFeedbackChanged(isolate(), GetHostFunction());
}
void IC::ConfigureVectorState(MapHandleList* maps,
List<Handle<Object>>* handlers) {
DCHECK(IsKeyedStoreIC());
KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
nexus->ConfigurePolymorphic(maps, handlers);
vector_set_ = true;
OnFeedbackChanged(isolate(), GetHostFunction());
}
MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
// If the object is undefined or null it's illegal to try to get any
// of its properties; throw a TypeError in that case.
@ -2167,7 +2076,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
List<Handle<Object>> handlers(target_receiver_maps.length());
StoreElementPolymorphicHandlers(&target_receiver_maps, &handlers, store_mode);
ConfigureVectorState(&target_receiver_maps, &handlers);
ConfigureVectorState(Handle<Name>(), &target_receiver_maps, &handlers);
}

View File

@ -97,10 +97,6 @@ class IC {
// Configure the vector for POLYMORPHIC.
void ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
List<Handle<Object>>* handlers);
// Configure the vector for POLYMORPHIC with transitions (only for element
// keyed stores).
void ConfigureVectorState(MapHandleList* maps,
List<Handle<Object>>* handlers);
char TransitionMarkFromState(IC::State state);
void TraceIC(const char* type, Handle<Object> name);

View File

@ -659,12 +659,12 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
if (name->IsUniqueName()) {
nexus.ConfigureMonomorphic(name, handle(object->map()));
} else {
nexus.ConfigureMegamorphic();
nexus.ConfigureMegamorphic(PROPERTY);
}
} else if (nexus.ic_state() == MONOMORPHIC) {
if (nexus.FindFirstMap() != object->map() ||
nexus.GetFeedbackExtra() != *name) {
nexus.ConfigureMegamorphic();
nexus.ConfigureMegamorphic(PROPERTY);
}
}