[ic] Introduce IsXyzIC() predicates.

This is a step towards encoding all the necessary information in
the feedback slot kind instead of storing it in the IC dispatcher's
code object flags.

BUG=v8:5849, v8:5917

Review-Url: https://codereview.chromium.org/2662113005
Cr-Commit-Position: refs/heads/master@{#42859}
This commit is contained in:
ishell 2017-02-01 08:22:03 -08:00 committed by Commit bot
parent c00aeb0300
commit 93f181b6b9
8 changed files with 150 additions and 92 deletions

View File

@ -564,7 +564,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
// We do not handle generic calls in try blocks.
if (is_exceptional) return NoChange();
// We only handle the generic store IC case.
if (vector->GetKind(slot) != FeedbackVectorSlotKind::STORE_IC) {
if (!vector->IsStoreIC(slot)) {
return NoChange();
}
}
@ -1556,7 +1556,7 @@ JSNativeContextSpecialization::BuildPropertyAccess(
} else {
DCHECK(access_info.IsGeneric());
DCHECK_EQ(AccessMode::kStore, access_mode);
DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
DCHECK(vector->IsStoreIC(slot));
Callable callable =
CodeFactory::StoreICInOptimizedCode(isolate(), language_mode);
const CallInterfaceDescriptor& descriptor = callable.descriptor();

View File

@ -6836,6 +6836,7 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
if (access_type == LOAD) {
HValue* values[] = {object, key, slot_value, vector_value};
if (!expr->AsProperty()->key()->IsPropertyName()) {
DCHECK(vector->IsKeyedLoadIC(slot));
// It's possible that a keyed load of a constant string was converted
// to a named load. Here, at the last minute, we need to make sure to
// use a generic Keyed Load if we are using the type vector, because
@ -6847,6 +6848,7 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
callable.descriptor(), ArrayVector(values));
return result;
}
DCHECK(vector->IsLoadIC(slot));
Callable callable = CodeFactory::LoadICInOptimizedCode(isolate());
HValue* stub = Add<HConstant>(callable.code());
HCallWithDescriptor* result = New<HCallWithDescriptor>(
@ -6855,7 +6857,7 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
} else {
HValue* values[] = {object, key, value, slot_value, vector_value};
if (vector->GetKind(slot) == FeedbackVectorSlotKind::KEYED_STORE_IC) {
if (vector->IsKeyedStoreIC(slot)) {
// It's possible that a keyed store of a constant string was converted
// to a named store. Here, at the last minute, we need to make sure to
// use a generic Keyed Store if we are using the type vector, because
@ -6868,6 +6870,7 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
callable.descriptor(), ArrayVector(values));
return result;
}
DCHECK(vector->IsStoreIC(slot));
Callable callable = CodeFactory::StoreICInOptimizedCode(
isolate(), function_language_mode());
HValue* stub = Add<HConstant>(callable.code());

View File

@ -2561,13 +2561,13 @@ RUNTIME_FUNCTION(Runtime_LoadIC_Miss) {
// LoadIC miss handler if the handler misses. Since the vector Nexus is
// set up outside the IC, handle that here.
FeedbackVectorSlotKind kind = vector->GetKind(vector_slot);
if (kind == FeedbackVectorSlotKind::LOAD_IC) {
if (IsLoadICKind(kind)) {
LoadICNexus nexus(vector, vector_slot);
LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
} else if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) {
} else if (IsLoadGlobalICKind(kind)) {
DCHECK_EQ(*isolate->global_object(), *receiver);
LoadGlobalICNexus nexus(vector, vector_slot);
LoadGlobalIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
@ -2575,7 +2575,7 @@ RUNTIME_FUNCTION(Runtime_LoadIC_Miss) {
RETURN_RESULT_OR_FAILURE(isolate, ic.Load(key));
} else {
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, kind);
DCHECK(IsKeyedLoadICKind(kind));
KeyedLoadICNexus nexus(vector, vector_slot);
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
@ -2671,14 +2671,13 @@ RUNTIME_FUNCTION(Runtime_StoreIC_Miss) {
Handle<Object> receiver = args.at(3);
Handle<Name> key = args.at<Name>(4);
FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) {
if (vector->IsStoreIC(vector_slot)) {
StoreICNexus nexus(vector, vector_slot);
StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
} else {
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC,
vector->GetKind(vector_slot));
DCHECK(vector->IsKeyedStoreIC(vector_slot));
KeyedStoreICNexus nexus(vector, vector_slot);
KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);

View File

@ -51,17 +51,29 @@ TypeFeedbackVector* TypeFeedbackVector::cast(Object* obj) {
int TypeFeedbackMetadata::GetSlotSize(FeedbackVectorSlotKind kind) {
DCHECK_NE(FeedbackVectorSlotKind::INVALID, kind);
DCHECK_NE(FeedbackVectorSlotKind::KINDS_NUMBER, kind);
if (kind == FeedbackVectorSlotKind::GENERAL ||
kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC ||
kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC ||
kind == FeedbackVectorSlotKind::LITERAL ||
kind == FeedbackVectorSlotKind::CREATE_CLOSURE) {
return 1;
}
switch (kind) {
case FeedbackVectorSlotKind::GENERAL:
case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC:
case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC:
case FeedbackVectorSlotKind::LITERAL:
case FeedbackVectorSlotKind::CREATE_CLOSURE:
return 1;
return 2;
case FeedbackVectorSlotKind::CALL_IC:
case FeedbackVectorSlotKind::LOAD_IC:
case FeedbackVectorSlotKind::LOAD_GLOBAL_IC:
case FeedbackVectorSlotKind::KEYED_LOAD_IC:
case FeedbackVectorSlotKind::STORE_IC:
case FeedbackVectorSlotKind::KEYED_STORE_IC:
case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC:
return 2;
case FeedbackVectorSlotKind::INVALID:
case FeedbackVectorSlotKind::KINDS_NUMBER:
UNREACHABLE();
break;
}
return 1;
}
bool TypeFeedbackVector::is_empty() const {
@ -174,6 +186,21 @@ void TypeFeedbackVector::ComputeCounts(int* with_type_info, int* generic,
break;
}
case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC:
// If we are not running interpreted code, we need to ignore the special
// IC slots for binaryop/compare used by the interpreter.
// TODO(mvstanton): Remove code_is_interpreted when full code is retired
// from service.
if (code_is_interpreted) {
int const feedback = Smi::cast(obj)->value();
BinaryOperationHint hint = BinaryOperationHintFromFeedback(feedback);
if (hint == BinaryOperationHint::kAny) {
gen++;
} else if (hint != BinaryOperationHint::kNone) {
with++;
}
total++;
}
break;
case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: {
// If we are not running interpreted code, we need to ignore the special
// IC slots for binaryop/compare used by the interpreter.
@ -181,23 +208,12 @@ void TypeFeedbackVector::ComputeCounts(int* with_type_info, int* generic,
// from service.
if (code_is_interpreted) {
int const feedback = Smi::cast(obj)->value();
if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC) {
CompareOperationHint hint =
CompareOperationHintFromFeedback(feedback);
if (hint == CompareOperationHint::kAny) {
gen++;
} else if (hint != CompareOperationHint::kNone) {
with++;
}
} else {
DCHECK_EQ(FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC, kind);
BinaryOperationHint hint =
BinaryOperationHintFromFeedback(feedback);
if (hint == BinaryOperationHint::kAny) {
gen++;
} else if (hint != BinaryOperationHint::kNone) {
with++;
}
CompareOperationHint hint =
CompareOperationHintFromFeedback(feedback);
if (hint == CompareOperationHint::kAny) {
gen++;
} else if (hint != CompareOperationHint::kNone) {
with++;
}
total++;
}

View File

@ -197,19 +197,6 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::New(
array->set_map_no_write_barrier(isolate->heap()->type_feedback_vector_map());
array->set(kMetadataIndex, *metadata);
array->set(kInvocationCountIndex, Smi::kZero);
for (int i = 0; i < slot_count;) {
FeedbackVectorSlot slot(i);
FeedbackVectorSlotKind kind = metadata->GetKind(slot);
int index = TypeFeedbackVector::GetIndex(slot);
int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
if (kind == FeedbackVectorSlotKind::CREATE_CLOSURE) {
// TODO(mvstanton): Root feedback vectors in this location.
array->set(index, *factory->empty_type_feedback_vector(),
SKIP_WRITE_BARRIER);
}
i += entry_size;
}
DisallowHeapAllocation no_gc;
@ -224,24 +211,44 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::New(
int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
Object* value;
if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) {
value = isolate->heap()->empty_weak_cell();
} else if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC ||
kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC) {
value = Smi::kZero;
} else if (kind == FeedbackVectorSlotKind::LITERAL) {
value = *undefined_value;
} else {
value = *uninitialized_sentinel;
}
Object* extra_value = *uninitialized_sentinel;
switch (kind) {
case FeedbackVectorSlotKind::LOAD_GLOBAL_IC:
value = isolate->heap()->empty_weak_cell();
break;
case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC:
case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC:
value = Smi::kZero;
break;
case FeedbackVectorSlotKind::CREATE_CLOSURE:
// TODO(mvstanton): Root feedback vectors in this location.
value = isolate->heap()->empty_type_feedback_vector();
break;
case FeedbackVectorSlotKind::LITERAL:
value = *undefined_value;
break;
case FeedbackVectorSlotKind::CALL_IC:
value = *uninitialized_sentinel;
extra_value = Smi::kZero;
break;
case FeedbackVectorSlotKind::LOAD_IC:
case FeedbackVectorSlotKind::KEYED_LOAD_IC:
case FeedbackVectorSlotKind::STORE_IC:
case FeedbackVectorSlotKind::KEYED_STORE_IC:
case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC:
case FeedbackVectorSlotKind::GENERAL:
value = *uninitialized_sentinel;
break;
if (kind != FeedbackVectorSlotKind::CREATE_CLOSURE) {
array->set(index, value, SKIP_WRITE_BARRIER);
value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero
: *uninitialized_sentinel;
for (int j = 1; j < entry_size; j++) {
array->set(index + j, value, SKIP_WRITE_BARRIER);
}
case FeedbackVectorSlotKind::INVALID:
case FeedbackVectorSlotKind::KINDS_NUMBER:
UNREACHABLE();
value = Smi::kZero;
break;
}
array->set(index, value, SKIP_WRITE_BARRIER);
for (int j = 1; j < entry_size; j++) {
array->set(index + j, extra_value, SKIP_WRITE_BARRIER);
}
i += entry_size;
}
@ -418,8 +425,8 @@ void FeedbackNexus::ConfigurePremonomorphic() {
void FeedbackNexus::ConfigureMegamorphic() {
// Keyed ICs must use ConfigureMegamorphicKeyed.
DCHECK_NE(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector()->GetKind(slot()));
DCHECK_NE(FeedbackVectorSlotKind::KEYED_STORE_IC, vector()->GetKind(slot()));
DCHECK(!vector()->IsKeyedLoadIC(slot()));
DCHECK(!vector()->IsKeyedStoreIC(slot()));
Isolate* isolate = GetIsolate();
SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(isolate),

View File

@ -39,6 +39,30 @@ enum class FeedbackVectorSlotKind {
KINDS_NUMBER // Last value indicating number of kinds.
};
inline bool IsCallICKind(FeedbackVectorSlotKind kind) {
return kind == FeedbackVectorSlotKind::CALL_IC;
}
inline bool IsLoadICKind(FeedbackVectorSlotKind kind) {
return kind == FeedbackVectorSlotKind::LOAD_IC;
}
inline bool IsLoadGlobalICKind(FeedbackVectorSlotKind kind) {
return kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC;
}
inline bool IsKeyedLoadICKind(FeedbackVectorSlotKind kind) {
return kind == FeedbackVectorSlotKind::KEYED_LOAD_IC;
}
inline bool IsStoreICKind(FeedbackVectorSlotKind kind) {
return kind == FeedbackVectorSlotKind::STORE_IC;
}
inline bool IsKeyedStoreICKind(FeedbackVectorSlotKind kind) {
return kind == FeedbackVectorSlotKind::KEYED_STORE_IC;
}
std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind);
@ -259,6 +283,17 @@ class TypeFeedbackVector : public FixedArray {
static Handle<TypeFeedbackVector> Copy(Isolate* isolate,
Handle<TypeFeedbackVector> vector);
#define DEFINE_SLOT_KIND_PREDICATE(Name) \
bool Name(FeedbackVectorSlot slot) const { return Name##Kind(GetKind(slot)); }
DEFINE_SLOT_KIND_PREDICATE(IsCallIC)
DEFINE_SLOT_KIND_PREDICATE(IsLoadIC)
DEFINE_SLOT_KIND_PREDICATE(IsLoadGlobalIC)
DEFINE_SLOT_KIND_PREDICATE(IsKeyedLoadIC)
DEFINE_SLOT_KIND_PREDICATE(IsStoreIC)
DEFINE_SLOT_KIND_PREDICATE(IsKeyedStoreIC)
#undef DEFINE_SLOT_KIND_PREDICATE
#ifdef OBJECT_PRINT
// For gdb debugging.
void Print();
@ -375,6 +410,7 @@ class FeedbackNexus {
return vector_handle_.is_null() ? vector_ : *vector_handle_;
}
FeedbackVectorSlot slot() const { return slot_; }
FeedbackVectorSlotKind kind() const { return vector()->GetKind(slot()); }
InlineCacheState ic_state() const { return StateFromFeedback(); }
bool IsUninitialized() const { return StateFromFeedback() == UNINITIALIZED; }
@ -430,11 +466,11 @@ class CallICNexus final : public FeedbackNexus {
public:
CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
DCHECK(vector->IsCallIC(slot));
}
CallICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
DCHECK(vector->IsCallIC(slot));
}
void Clear(Code* host);
@ -471,7 +507,7 @@ class LoadICNexus : public FeedbackNexus {
public:
LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
DCHECK(vector->IsLoadIC(slot));
}
explicit LoadICNexus(Isolate* isolate)
: FeedbackNexus(
@ -479,7 +515,7 @@ class LoadICNexus : public FeedbackNexus {
FeedbackVectorSlot(TypeFeedbackVector::kDummyLoadICSlot)) {}
LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
DCHECK(vector->IsLoadIC(slot));
}
void Clear(Code* host);
@ -496,11 +532,11 @@ class LoadGlobalICNexus : public FeedbackNexus {
public:
LoadGlobalICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, vector->GetKind(slot));
DCHECK(vector->IsLoadGlobalIC(slot));
}
LoadGlobalICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, vector->GetKind(slot));
DCHECK(vector->IsLoadGlobalIC(slot));
}
int ExtractMaps(MapHandleList* maps) const final {
@ -529,7 +565,7 @@ class KeyedLoadICNexus : public FeedbackNexus {
public:
KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
DCHECK(vector->IsKeyedLoadIC(slot));
}
explicit KeyedLoadICNexus(Isolate* isolate)
: FeedbackNexus(
@ -537,7 +573,7 @@ class KeyedLoadICNexus : public FeedbackNexus {
FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedLoadICSlot)) {}
KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
DCHECK(vector->IsKeyedLoadIC(slot));
}
void Clear(Code* host);
@ -561,7 +597,7 @@ class StoreICNexus : public FeedbackNexus {
public:
StoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
DCHECK(vector->IsStoreIC(slot));
}
explicit StoreICNexus(Isolate* isolate)
: FeedbackNexus(
@ -569,7 +605,7 @@ class StoreICNexus : public FeedbackNexus {
FeedbackVectorSlot(TypeFeedbackVector::kDummyStoreICSlot)) {}
StoreICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
DCHECK(vector->IsStoreIC(slot));
}
void Clear(Code* host);
@ -587,7 +623,7 @@ class KeyedStoreICNexus : public FeedbackNexus {
public:
KeyedStoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
DCHECK(vector->IsKeyedStoreIC(slot));
}
explicit KeyedStoreICNexus(Isolate* isolate)
: FeedbackNexus(
@ -595,7 +631,7 @@ class KeyedStoreICNexus : public FeedbackNexus {
FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)) {}
KeyedStoreICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
: FeedbackNexus(vector, slot) {
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
DCHECK(vector->IsKeyedStoreIC(slot));
}
void Clear(Code* host);

View File

@ -75,10 +75,10 @@ InlineCacheState TypeFeedbackOracle::LoadInlineCacheState(
FeedbackVectorSlot slot) {
if (!slot.IsInvalid()) {
FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot);
if (kind == FeedbackVectorSlotKind::LOAD_IC) {
if (IsLoadICKind(kind)) {
LoadICNexus nexus(feedback_vector_, slot);
return nexus.StateFromFeedback();
} else if (kind == FeedbackVectorSlotKind::KEYED_LOAD_IC) {
} else if (IsKeyedLoadICKind(kind)) {
KeyedLoadICNexus nexus(feedback_vector_, slot);
return nexus.StateFromFeedback();
}
@ -93,10 +93,10 @@ InlineCacheState TypeFeedbackOracle::LoadInlineCacheState(
bool TypeFeedbackOracle::StoreIsUninitialized(FeedbackVectorSlot slot) {
if (!slot.IsInvalid()) {
FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot);
if (kind == FeedbackVectorSlotKind::STORE_IC) {
if (IsStoreICKind(kind)) {
StoreICNexus nexus(feedback_vector_, slot);
return nexus.StateFromFeedback() == UNINITIALIZED;
} else if (kind == FeedbackVectorSlotKind::KEYED_STORE_IC) {
} else if (IsKeyedStoreICKind(kind)) {
KeyedStoreICNexus nexus(feedback_vector_, slot);
return nexus.StateFromFeedback() == UNINITIALIZED;
}
@ -137,9 +137,7 @@ byte TypeFeedbackOracle::ForInType(FeedbackVectorSlot feedback_vector_slot) {
void TypeFeedbackOracle::GetStoreModeAndKeyType(
FeedbackVectorSlot slot, KeyedAccessStoreMode* store_mode,
IcCheckType* key_type) {
if (!slot.IsInvalid() &&
feedback_vector_->GetKind(slot) ==
FeedbackVectorSlotKind::KEYED_STORE_IC) {
if (!slot.IsInvalid() && feedback_vector_->IsKeyedStoreIC(slot)) {
KeyedStoreICNexus nexus(feedback_vector_, slot);
*store_mode = nexus.GetKeyedAccessStoreMode();
*key_type = nexus.GetKeyType();
@ -477,12 +475,11 @@ void TypeFeedbackOracle::CollectReceiverTypes(StubCache* stub_cache,
void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorSlot slot,
SmallMapList* types) {
FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot);
if (kind == FeedbackVectorSlotKind::STORE_IC) {
if (feedback_vector_->IsStoreIC(slot)) {
StoreICNexus nexus(feedback_vector_, slot);
CollectReceiverTypes(&nexus, types);
} else {
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, kind);
DCHECK(feedback_vector_->IsKeyedStoreIC(slot));
KeyedStoreICNexus nexus(feedback_vector_, slot);
CollectReceiverTypes(&nexus, types);
}

View File

@ -3776,11 +3776,11 @@ static void CheckVectorIC(Handle<JSFunction> f, int slot_index,
Handle<TypeFeedbackVector>(f->feedback_vector());
FeedbackVectorHelper helper(vector);
FeedbackVectorSlot slot = helper.slot(slot_index);
if (vector->GetKind(slot) == FeedbackVectorSlotKind::LOAD_IC) {
if (vector->IsLoadIC(slot)) {
LoadICNexus nexus(vector, slot);
CHECK(nexus.StateFromFeedback() == desired_state);
} else {
CHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
CHECK(vector->IsKeyedLoadIC(slot));
KeyedLoadICNexus nexus(vector, slot);
CHECK(nexus.StateFromFeedback() == desired_state);
}