[ic] Fix -Wshadow by making InlineCacheState an enum class

Bug: v8:12244,v8:12245
Change-Id: Ie2b1801d7535e142774a1d912b992a203b1b8ecc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3284005
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78000}
This commit is contained in:
Ng Zhi An 2021-11-19 10:02:26 -08:00 committed by V8 LUCI CQ
parent 4dab3a31f7
commit f47eec071e
12 changed files with 147 additions and 122 deletions

View File

@ -959,7 +959,7 @@ enum ParseRestriction : bool {
};
// State for inline cache call sites. Aliased as IC::State.
enum InlineCacheState {
enum class InlineCacheState {
// No feedback will be collected.
NO_FEEDBACK,
// Has never been executed.
@ -978,24 +978,26 @@ enum InlineCacheState {
GENERIC,
};
inline size_t hash_value(InlineCacheState mode) { return bit_cast<int>(mode); }
// Printing support.
inline const char* InlineCacheState2String(InlineCacheState state) {
switch (state) {
case NO_FEEDBACK:
case InlineCacheState::NO_FEEDBACK:
return "NOFEEDBACK";
case UNINITIALIZED:
case InlineCacheState::UNINITIALIZED:
return "UNINITIALIZED";
case MONOMORPHIC:
case InlineCacheState::MONOMORPHIC:
return "MONOMORPHIC";
case RECOMPUTE_HANDLER:
case InlineCacheState::RECOMPUTE_HANDLER:
return "RECOMPUTE_HANDLER";
case POLYMORPHIC:
case InlineCacheState::POLYMORPHIC:
return "POLYMORPHIC";
case MEGAMORPHIC:
case InlineCacheState::MEGAMORPHIC:
return "MEGAMORPHIC";
case MEGADOM:
case InlineCacheState::MEGADOM:
return "MEGADOM";
case GENERIC:
case InlineCacheState::GENERIC:
return "GENERIC";
}
UNREACHABLE();

View File

@ -582,13 +582,14 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForPropertyAccess(
// If no maps were found for a non-megamorphic access, then our maps died
// and we should soft-deopt.
if (maps.empty() && nexus.ic_state() != MEGAMORPHIC) {
if (maps.empty() && nexus.ic_state() != InlineCacheState::MEGAMORPHIC) {
return NewInsufficientFeedback(kind);
}
if (name.has_value()) {
// We rely on this invariant in JSGenericLowering.
DCHECK_IMPLIES(maps.empty(), nexus.ic_state() == MEGAMORPHIC);
DCHECK_IMPLIES(maps.empty(),
nexus.ic_state() == InlineCacheState::MEGAMORPHIC);
return *zone()->New<NamedAccessFeedback>(*name, maps, kind);
} else if (nexus.GetKeyType() == IcCheckType::kElement && !maps.empty()) {
return ProcessFeedbackMapsForElementAccess(
@ -596,7 +597,7 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForPropertyAccess(
} else {
// No actionable feedback.
DCHECK(maps.empty());
DCHECK_EQ(nexus.ic_state(), MEGAMORPHIC);
DCHECK_EQ(nexus.ic_state(), InlineCacheState::MEGAMORPHIC);
// TODO(neis): Using ElementAccessFeedback here is kind of an abuse.
return *zone()->New<ElementAccessFeedback>(
zone(), KeyedAccessMode::FromNexus(nexus), kind);
@ -611,7 +612,8 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForGlobalAccess(
nexus.kind() == FeedbackSlotKind::kStoreGlobalSloppy ||
nexus.kind() == FeedbackSlotKind::kStoreGlobalStrict);
if (nexus.IsUninitialized()) return NewInsufficientFeedback(nexus.kind());
if (nexus.ic_state() != MONOMORPHIC || nexus.GetFeedback()->IsCleared()) {
if (nexus.ic_state() != InlineCacheState::MONOMORPHIC ||
nexus.GetFeedback()->IsCleared()) {
return *zone()->New<GlobalAccessFeedback>(nexus.kind());
}

View File

@ -35,8 +35,8 @@ bool IC::IsHandler(MaybeObject object) {
}
bool IC::vector_needs_update() {
if (state() == NO_FEEDBACK) return false;
return (!vector_set_ && (state() != MEGAMORPHIC ||
if (state() == InlineCacheState::NO_FEEDBACK) return false;
return (!vector_set_ && (state() != InlineCacheState::MEGAMORPHIC ||
nexus()->GetKeyType() != IcCheckType::kElement));
}

View File

@ -50,6 +50,18 @@
namespace v8 {
namespace internal {
// Aliases to avoid having to repeat the class.
// With C++20 we can use "using" to introduce scoped enums.
constexpr InlineCacheState NO_FEEDBACK = InlineCacheState::NO_FEEDBACK;
constexpr InlineCacheState UNINITIALIZED = InlineCacheState::UNINITIALIZED;
constexpr InlineCacheState MONOMORPHIC = InlineCacheState::MONOMORPHIC;
constexpr InlineCacheState RECOMPUTE_HANDLER =
InlineCacheState::RECOMPUTE_HANDLER;
constexpr InlineCacheState POLYMORPHIC = InlineCacheState::POLYMORPHIC;
constexpr InlineCacheState MEGAMORPHIC = InlineCacheState::MEGAMORPHIC;
constexpr InlineCacheState MEGADOM = InlineCacheState::MEGADOM;
constexpr InlineCacheState GENERIC = InlineCacheState::GENERIC;
char IC::TransitionMarkFromState(IC::State state) {
switch (state) {
case NO_FEEDBACK:

View File

@ -45,7 +45,7 @@ class IC {
void MarkRecomputeHandler(Handle<Object> name) {
DCHECK(RecomputeHandlerForName(name));
old_state_ = state_;
state_ = RECOMPUTE_HANDLER;
state_ = InlineCacheState::RECOMPUTE_HANDLER;
}
bool IsAnyHas() const { return IsKeyedHasIC(); }

View File

@ -725,20 +725,20 @@ InlineCacheState FeedbackNexus::ic_state() const {
switch (kind()) {
case FeedbackSlotKind::kLiteral:
if (feedback->IsSmi()) return UNINITIALIZED;
return MONOMORPHIC;
if (feedback->IsSmi()) return InlineCacheState::UNINITIALIZED;
return InlineCacheState::MONOMORPHIC;
case FeedbackSlotKind::kStoreGlobalSloppy:
case FeedbackSlotKind::kStoreGlobalStrict:
case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
case FeedbackSlotKind::kLoadGlobalInsideTypeof: {
if (feedback->IsSmi()) return MONOMORPHIC;
if (feedback->IsSmi()) return InlineCacheState::MONOMORPHIC;
DCHECK(feedback->IsWeakOrCleared());
if (!feedback->IsCleared() || extra != UninitializedSentinel()) {
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
}
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
}
case FeedbackSlotKind::kStoreNamedSloppy:
@ -752,32 +752,33 @@ InlineCacheState FeedbackNexus::ic_state() const {
case FeedbackSlotKind::kLoadKeyed:
case FeedbackSlotKind::kHasKeyed: {
if (feedback == UninitializedSentinel()) {
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
}
if (feedback == MegamorphicSentinel()) {
return MEGAMORPHIC;
return InlineCacheState::MEGAMORPHIC;
}
if (feedback == MegaDOMSentinel()) {
DCHECK(IsLoadICKind(kind()));
return MEGADOM;
return InlineCacheState::MEGADOM;
}
if (feedback->IsWeakOrCleared()) {
// Don't check if the map is cleared.
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
}
HeapObject heap_object;
if (feedback->GetHeapObjectIfStrong(&heap_object)) {
if (heap_object.IsWeakFixedArray()) {
// Determine state purely by our structure, don't check if the maps
// are cleared.
return POLYMORPHIC;
return InlineCacheState::POLYMORPHIC;
}
if (heap_object.IsName()) {
DCHECK(IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
IsKeyedHasICKind(kind()) || IsDefineOwnICKind(kind()));
Object extra_object = extra->GetHeapObjectAssumeStrong();
WeakFixedArray extra_array = WeakFixedArray::cast(extra_object);
return extra_array.length() > 2 ? POLYMORPHIC : MONOMORPHIC;
return extra_array.length() > 2 ? InlineCacheState::POLYMORPHIC
: InlineCacheState::MONOMORPHIC;
}
}
UNREACHABLE();
@ -785,97 +786,97 @@ InlineCacheState FeedbackNexus::ic_state() const {
case FeedbackSlotKind::kCall: {
HeapObject heap_object;
if (feedback == MegamorphicSentinel()) {
return GENERIC;
return InlineCacheState::GENERIC;
} else if (feedback->IsWeakOrCleared()) {
if (feedback->GetHeapObjectIfWeak(&heap_object)) {
if (heap_object.IsFeedbackCell()) {
return POLYMORPHIC;
return InlineCacheState::POLYMORPHIC;
}
CHECK(heap_object.IsJSFunction() || heap_object.IsJSBoundFunction());
}
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
} else if (feedback->GetHeapObjectIfStrong(&heap_object) &&
heap_object.IsAllocationSite()) {
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
}
CHECK_EQ(feedback, UninitializedSentinel());
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
}
case FeedbackSlotKind::kBinaryOp: {
BinaryOperationHint hint = GetBinaryOperationFeedback();
if (hint == BinaryOperationHint::kNone) {
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
} else if (hint == BinaryOperationHint::kAny) {
return GENERIC;
return InlineCacheState::GENERIC;
}
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
}
case FeedbackSlotKind::kCompareOp: {
CompareOperationHint hint = GetCompareOperationFeedback();
if (hint == CompareOperationHint::kNone) {
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
} else if (hint == CompareOperationHint::kAny) {
return GENERIC;
return InlineCacheState::GENERIC;
}
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
}
case FeedbackSlotKind::kForIn: {
ForInHint hint = GetForInFeedback();
if (hint == ForInHint::kNone) {
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
} else if (hint == ForInHint::kAny) {
return GENERIC;
return InlineCacheState::GENERIC;
}
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
}
case FeedbackSlotKind::kInstanceOf: {
if (feedback == UninitializedSentinel()) {
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
} else if (feedback == MegamorphicSentinel()) {
return MEGAMORPHIC;
return InlineCacheState::MEGAMORPHIC;
}
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
}
case FeedbackSlotKind::kStoreDataPropertyInLiteral: {
if (feedback == UninitializedSentinel()) {
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
} else if (feedback->IsWeakOrCleared()) {
// Don't check if the map is cleared.
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
}
return MEGAMORPHIC;
return InlineCacheState::MEGAMORPHIC;
}
case FeedbackSlotKind::kTypeProfile: {
if (feedback == UninitializedSentinel()) {
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
}
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
}
case FeedbackSlotKind::kCloneObject: {
if (feedback == UninitializedSentinel()) {
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
}
if (feedback == MegamorphicSentinel()) {
return MEGAMORPHIC;
return InlineCacheState::MEGAMORPHIC;
}
if (feedback->IsWeakOrCleared()) {
return MONOMORPHIC;
return InlineCacheState::MONOMORPHIC;
}
DCHECK(feedback->GetHeapObjectAssumeStrong().IsWeakFixedArray());
return POLYMORPHIC;
return InlineCacheState::POLYMORPHIC;
}
case FeedbackSlotKind::kInvalid:
case FeedbackSlotKind::kKindsNumber:
UNREACHABLE();
}
return UNINITIALIZED;
return InlineCacheState::UNINITIALIZED;
}
void FeedbackNexus::ConfigurePropertyCellMode(Handle<PropertyCell> cell) {
@ -925,12 +926,12 @@ void FeedbackNexus::ConfigureCloneObject(Handle<Map> source_map,
}
}
switch (ic_state()) {
case UNINITIALIZED:
case InlineCacheState::UNINITIALIZED:
// Cache the first map seen which meets the fast case requirements.
SetFeedback(HeapObjectReference::Weak(*source_map), UPDATE_WRITE_BARRIER,
*result_map);
break;
case MONOMORPHIC:
case InlineCacheState::MONOMORPHIC:
if (feedback.is_null() || feedback.is_identical_to(source_map) ||
Map::cast(*feedback).is_deprecated()) {
SetFeedback(HeapObjectReference::Weak(*source_map),
@ -947,7 +948,7 @@ void FeedbackNexus::ConfigureCloneObject(Handle<Map> source_map,
HeapObjectReference::ClearedValue(isolate));
}
break;
case POLYMORPHIC: {
case InlineCacheState::POLYMORPHIC: {
const int kMaxElements = FLAG_max_valid_polymorphic_map_count *
kCloneObjectPolymorphicEntrySize;
Handle<WeakFixedArray> array = Handle<WeakFixedArray>::cast(feedback);

View File

@ -747,9 +747,13 @@ class V8_EXPORT_PRIVATE FeedbackNexus final {
}
InlineCacheState ic_state() const;
bool IsUninitialized() const { return ic_state() == UNINITIALIZED; }
bool IsMegamorphic() const { return ic_state() == MEGAMORPHIC; }
bool IsGeneric() const { return ic_state() == GENERIC; }
bool IsUninitialized() const {
return ic_state() == InlineCacheState::UNINITIALIZED;
}
bool IsMegamorphic() const {
return ic_state() == InlineCacheState::MEGAMORPHIC;
}
bool IsGeneric() const { return ic_state() == InlineCacheState::GENERIC; }
void Print(std::ostream& os);
@ -773,7 +777,7 @@ class V8_EXPORT_PRIVATE FeedbackNexus final {
bool IsCleared() const {
InlineCacheState state = ic_state();
return !FLAG_use_ic || state == UNINITIALIZED;
return !FLAG_use_ic || state == InlineCacheState::UNINITIALIZED;
}
// Clear() returns true if the state of the underlying vector was changed.

View File

@ -1095,14 +1095,14 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
DCHECK(maybe_vector->IsFeedbackVector());
Handle<FeedbackVector> vector = Handle<FeedbackVector>::cast(maybe_vector);
FeedbackNexus nexus(vector, FeedbackVector::ToSlot(index));
if (nexus.ic_state() == UNINITIALIZED) {
if (nexus.ic_state() == InlineCacheState::UNINITIALIZED) {
if (name->IsUniqueName()) {
nexus.ConfigureMonomorphic(name, handle(object->map(), isolate),
MaybeObjectHandle());
} else {
nexus.ConfigureMegamorphic(IcCheckType::kProperty);
}
} else if (nexus.ic_state() == MONOMORPHIC) {
} else if (nexus.ic_state() == InlineCacheState::MONOMORPHIC) {
if (nexus.GetFirstMap() != object->map() || nexus.GetName() != *name) {
nexus.ConfigureMegamorphic(IcCheckType::kProperty);
}

View File

@ -3327,12 +3327,12 @@ TEST(IncrementalMarkingPreservesMonomorphicIC) {
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
CheckVectorIC(f, 0, MONOMORPHIC);
CheckVectorIC(f, 0, InlineCacheState::MONOMORPHIC);
heap::SimulateIncrementalMarking(CcTest::heap());
CcTest::CollectAllGarbage();
CheckVectorIC(f, 0, MONOMORPHIC);
CheckVectorIC(f, 0, InlineCacheState::MONOMORPHIC);
}
TEST(IncrementalMarkingPreservesPolymorphicIC) {
@ -3369,13 +3369,13 @@ TEST(IncrementalMarkingPreservesPolymorphicIC) {
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
CheckVectorIC(f, 0, POLYMORPHIC);
CheckVectorIC(f, 0, InlineCacheState::POLYMORPHIC);
// Fire context dispose notification.
heap::SimulateIncrementalMarking(CcTest::heap());
CcTest::CollectAllGarbage();
CheckVectorIC(f, 0, POLYMORPHIC);
CheckVectorIC(f, 0, InlineCacheState::POLYMORPHIC);
}
TEST(ContextDisposeDoesntClearPolymorphicIC) {
@ -3412,14 +3412,14 @@ TEST(ContextDisposeDoesntClearPolymorphicIC) {
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
CheckVectorIC(f, 0, POLYMORPHIC);
CheckVectorIC(f, 0, InlineCacheState::POLYMORPHIC);
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
heap::SimulateIncrementalMarking(CcTest::heap());
CcTest::CollectAllGarbage();
CheckVectorIC(f, 0, POLYMORPHIC);
CheckVectorIC(f, 0, InlineCacheState::POLYMORPHIC);
}
@ -4758,12 +4758,12 @@ TEST(MonomorphicStaysMonomorphicAfterGC) {
CompileRun("(testIC())");
}
CcTest::CollectAllGarbage();
CheckIC(loadIC, 0, MONOMORPHIC);
CheckIC(loadIC, 0, InlineCacheState::MONOMORPHIC);
{
v8::HandleScope new_scope(CcTest::isolate());
CompileRun("(testIC())");
}
CheckIC(loadIC, 0, MONOMORPHIC);
CheckIC(loadIC, 0, InlineCacheState::MONOMORPHIC);
}
@ -4797,12 +4797,12 @@ TEST(PolymorphicStaysPolymorphicAfterGC) {
CompileRun("(testIC())");
}
CcTest::CollectAllGarbage();
CheckIC(loadIC, 0, POLYMORPHIC);
CheckIC(loadIC, 0, InlineCacheState::POLYMORPHIC);
{
v8::HandleScope new_scope(CcTest::isolate());
CompileRun("(testIC())");
}
CheckIC(loadIC, 0, POLYMORPHIC);
CheckIC(loadIC, 0, InlineCacheState::POLYMORPHIC);
}
#ifdef DEBUG

View File

@ -10778,7 +10778,7 @@ THREADED_TEST(ShadowObjectAndDataProperty) {
i::FeedbackNexus nexus(foo->feedback_vector(), slot);
CHECK_EQ(i::FeedbackSlotKind::kStoreGlobalSloppy, nexus.kind());
CompileRun("foo(1)");
CHECK_EQ(i::MONOMORPHIC, nexus.ic_state());
CHECK_EQ(i::InlineCacheState::MONOMORPHIC, nexus.ic_state());
// We go a bit further, checking that the form of monomorphism is
// a PropertyCell in the vector. This is because we want to make sure
// we didn't settle for a "poor man's monomorphism," such as a
@ -10828,7 +10828,7 @@ THREADED_TEST(ShadowObjectAndDataPropertyTurbo) {
i::FeedbackNexus nexus(foo->feedback_vector(), slot);
CHECK_EQ(i::FeedbackSlotKind::kStoreGlobalSloppy, nexus.kind());
CompileRun("%OptimizeFunctionOnNextCall(foo); foo(1)");
CHECK_EQ(i::MONOMORPHIC, nexus.ic_state());
CHECK_EQ(i::InlineCacheState::MONOMORPHIC, nexus.ic_state());
i::HeapObject heap_object;
CHECK(nexus.GetFeedback().GetHeapObject(&heap_object));
CHECK(heap_object.IsPropertyCell());

View File

@ -40,12 +40,13 @@ class FeedbackVectorExplorationThread final : public v8::base::Thread {
vector_ready_(vector_ready),
vector_consumed_(vector_consumed) {}
using InlineCacheSet = std::unordered_set<InlineCacheState, std::hash<int>>;
using InlineCacheSet = std::unordered_set<InlineCacheState>;
bool AllRequiredStatesSeen(const InlineCacheSet& found) {
auto end = found.end();
return (found.find(UNINITIALIZED) != end &&
found.find(MONOMORPHIC) != end && found.find(POLYMORPHIC) != end &&
found.find(MEGAMORPHIC) != end);
return (found.find(InlineCacheState::UNINITIALIZED) != end &&
found.find(InlineCacheState::MONOMORPHIC) != end &&
found.find(InlineCacheState::POLYMORPHIC) != end &&
found.find(InlineCacheState::MEGAMORPHIC) != end);
}
void Run() override {
@ -65,7 +66,8 @@ class FeedbackVectorExplorationThread final : public v8::base::Thread {
for (int i = 0; i < kCycles; i++) {
FeedbackNexus nexus(feedback_vector_, slot, nexus_config);
auto state = nexus.ic_state();
if (state == MONOMORPHIC || state == POLYMORPHIC) {
if (state == InlineCacheState::MONOMORPHIC ||
state == InlineCacheState::POLYMORPHIC) {
MapHandles maps;
nexus.ExtractMaps(&maps);
for (unsigned int j = 0; j < maps.size(); j++) {
@ -93,7 +95,7 @@ class FeedbackVectorExplorationThread final : public v8::base::Thread {
{
FeedbackNexus nexus(feedback_vector_, slot, nexus_config);
auto state = nexus.ic_state();
CHECK_EQ(state, UNINITIALIZED);
CHECK_EQ(state, InlineCacheState::UNINITIALIZED);
}
vector_consumed_->Signal();
vector_ready_->Wait();
@ -101,7 +103,7 @@ class FeedbackVectorExplorationThread final : public v8::base::Thread {
{
FeedbackNexus nexus(feedback_vector_, slot, nexus_config);
auto state = nexus.ic_state();
CHECK_EQ(state, MONOMORPHIC);
CHECK_EQ(state, InlineCacheState::MONOMORPHIC);
MapHandles maps;
nexus.ExtractMaps(&maps);
CHECK(maps[0]->IsMap());
@ -112,7 +114,7 @@ class FeedbackVectorExplorationThread final : public v8::base::Thread {
{
FeedbackNexus nexus(feedback_vector_, slot, nexus_config);
auto state = nexus.ic_state();
CHECK_EQ(state, POLYMORPHIC);
CHECK_EQ(state, InlineCacheState::POLYMORPHIC);
MapHandles maps;
nexus.ExtractMaps(&maps);
for (unsigned int i = 0; i < maps.size(); i++) {
@ -125,7 +127,7 @@ class FeedbackVectorExplorationThread final : public v8::base::Thread {
{
FeedbackNexus nexus(feedback_vector_, slot, nexus_config);
auto state = nexus.ic_state();
CHECK_EQ(state, MEGAMORPHIC);
CHECK_EQ(state, InlineCacheState::MEGAMORPHIC);
}
}
@ -184,7 +186,7 @@ TEST(CheckLoadICStates) {
FeedbackSlot slot(0);
FeedbackNexus nexus(vector, slot);
CHECK(IsLoadICKind(nexus.kind()));
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
nexus.ConfigureUninitialized();
// Now the basic environment is set up. Start the worker thread.
@ -208,7 +210,7 @@ TEST(CheckLoadICStates) {
for (int i = 0; i < kCycles; i++) {
if (all_states_seen.load(std::memory_order_acquire)) break;
CHECK_EQ(UNINITIALIZED, nexus.ic_state());
CHECK_EQ(InlineCacheState::UNINITIALIZED, nexus.ic_state());
if (i == (kCycles - 1)) {
// If we haven't seen all states by the last attempt, enter an explicit
// handshaking mode.
@ -218,7 +220,7 @@ TEST(CheckLoadICStates) {
}
nexus.ConfigureMonomorphic(Handle<Name>(), Handle<Map>(o1->map(), isolate),
dummy_handler);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
if (i == (kCycles - 1)) {
vector_ready.Signal();
@ -237,7 +239,7 @@ TEST(CheckLoadICStates) {
map_and_handlers.push_back(
MapAndHandler(Handle<Map>(o4->map(), isolate), dummy_handler));
nexus.ConfigurePolymorphic(Handle<Name>(), map_and_handlers);
CHECK_EQ(POLYMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
if (i == (kCycles - 1)) {
vector_ready.Signal();
@ -247,7 +249,7 @@ TEST(CheckLoadICStates) {
// Go Megamorphic
nexus.ConfigureMegamorphic();
CHECK_EQ(MEGAMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MEGAMORPHIC, nexus.ic_state());
if (i == (kCycles - 1)) {
vector_ready.Signal();

View File

@ -174,14 +174,14 @@ TEST(VectorCallICStates) {
Handle<FeedbackVector>(f->feedback_vector(), isolate);
FeedbackSlot slot(0);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
CompileRun("f(function() { return 16; })");
CHECK_EQ(GENERIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::GENERIC, nexus.ic_state());
// After a collection, state should remain GENERIC.
CcTest::CollectAllGarbage();
CHECK_EQ(GENERIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::GENERIC, nexus.ic_state());
}
// Test the Call IC states transfer with Function.prototype.apply
@ -207,7 +207,7 @@ TEST(VectorCallICStateApply) {
Handle<FeedbackVector>(foo->feedback_vector(), isolate);
FeedbackSlot slot(4);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
HeapObject heap_object;
CHECK(nexus.GetFeedback()->GetHeapObjectIfWeak(&heap_object));
@ -216,7 +216,7 @@ TEST(VectorCallICStateApply) {
CompileRun(
"F = Math.max;"
"foo();");
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
CHECK_EQ(CallFeedbackContent::kTarget, nexus.GetCallFeedbackContent());
CHECK(nexus.GetFeedback()->GetHeapObjectIfWeak(&heap_object));
CHECK_EQ(*isolate->function_prototype_apply(), heap_object);
@ -224,7 +224,7 @@ TEST(VectorCallICStateApply) {
CompileRun(
"F.apply = (function () { return; });"
"foo();");
CHECK_EQ(GENERIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::GENERIC, nexus.ic_state());
}
TEST(VectorCallFeedback) {
@ -249,14 +249,14 @@ TEST(VectorCallFeedback) {
FeedbackSlot slot(0);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
HeapObject heap_object;
CHECK(nexus.GetFeedback()->GetHeapObjectIfWeak(&heap_object));
CHECK_EQ(*foo, heap_object);
CcTest::CollectAllGarbage();
// It should stay monomorphic even after a GC.
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
}
TEST(VectorPolymorphicCallFeedback) {
@ -283,7 +283,7 @@ TEST(VectorPolymorphicCallFeedback) {
FeedbackSlot slot(0);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(POLYMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
HeapObject heap_object;
CHECK(nexus.GetFeedback()->GetHeapObjectIfWeak(&heap_object));
CHECK(heap_object.IsFeedbackCell(isolate));
@ -313,14 +313,14 @@ TEST(VectorCallFeedbackForArray) {
FeedbackSlot slot(0);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
HeapObject heap_object;
CHECK(nexus.GetFeedback()->GetHeapObjectIfWeak(&heap_object));
CHECK_EQ(*isolate->array_function(), heap_object);
CcTest::CollectAllGarbage();
// It should stay monomorphic even after a GC.
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
}
TEST(VectorCallCounts) {
@ -344,15 +344,15 @@ TEST(VectorCallCounts) {
Handle<FeedbackVector>(f->feedback_vector(), isolate);
FeedbackSlot slot(0);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
CompileRun("f(foo); f(foo);");
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
CHECK_EQ(3, nexus.GetCallCount());
// Send the IC megamorphic, but we should still have incrementing counts.
CompileRun("f(function() { return 12; });");
CHECK_EQ(GENERIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::GENERIC, nexus.ic_state());
CHECK_EQ(4, nexus.GetCallCount());
}
@ -377,17 +377,17 @@ TEST(VectorConstructCounts) {
FeedbackSlot slot(0);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
CHECK(feedback_vector->Get(slot)->IsWeak());
CompileRun("f(Foo); f(Foo);");
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
CHECK_EQ(3, nexus.GetCallCount());
// Send the IC megamorphic, but we should still have incrementing counts.
CompileRun("f(function() {});");
CHECK_EQ(GENERIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::GENERIC, nexus.ic_state());
CHECK_EQ(4, nexus.GetCallCount());
}
@ -452,15 +452,15 @@ TEST(VectorCallSpeculationModeAndFeedbackContent) {
FeedbackSlot slot(6);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
CHECK_EQ(SpeculationMode::kAllowSpeculation, nexus.GetSpeculationMode());
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
CompileRun("%OptimizeFunctionOnNextCall(f); f(1);");
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
CHECK_EQ(SpeculationMode::kAllowSpeculation, nexus.GetSpeculationMode());
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
CompileRun("f({});"); // Deoptimizes.
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
CHECK_EQ(SpeculationMode::kDisallowSpeculation, nexus.GetSpeculationMode());
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
}
@ -487,7 +487,7 @@ TEST(VectorLoadICStates) {
FeedbackSlot slot(0);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
// Verify that the monomorphic map is the one we expect.
v8::MaybeLocal<v8::Value> v8_o =
CcTest::global()->Get(context.local(), v8_str("o"));
@ -497,27 +497,27 @@ TEST(VectorLoadICStates) {
// Now go polymorphic.
CompileRun("f({ blarg: 3, foo: 2 })");
CHECK_EQ(POLYMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
CompileRun(
"delete o.foo;"
"f(o)");
CHECK_EQ(POLYMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
CompileRun("f({ blarg: 3, torino: 10, foo: 2 })");
CHECK_EQ(POLYMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
MapHandles maps;
nexus.ExtractMaps(&maps);
CHECK_EQ(4, maps.size());
// Finally driven megamorphic.
CompileRun("f({ blarg: 3, gran: 3, torino: 10, foo: 2 })");
CHECK_EQ(MEGAMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MEGAMORPHIC, nexus.ic_state());
CHECK(nexus.GetFirstMap().is_null());
// After a collection, state should not be reset to PREMONOMORPHIC.
CcTest::CollectAllGarbage();
CHECK_EQ(MEGAMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MEGAMORPHIC, nexus.ic_state());
}
TEST(VectorLoadGlobalICSlotSharing) {
@ -552,8 +552,10 @@ TEST(VectorLoadGlobalICSlotSharing) {
CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kLoadGlobalInsideTypeof);
FeedbackSlot slot1 = helper.slot(0);
FeedbackSlot slot2 = helper.slot(1);
CHECK_EQ(MONOMORPHIC, FeedbackNexus(feedback_vector, slot1).ic_state());
CHECK_EQ(MONOMORPHIC, FeedbackNexus(feedback_vector, slot2).ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC,
FeedbackNexus(feedback_vector, slot1).ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC,
FeedbackNexus(feedback_vector, slot2).ic_state());
}
@ -579,14 +581,14 @@ TEST(VectorLoadICOnSmi) {
Handle<FeedbackVector>(f->feedback_vector(), isolate);
FeedbackSlot slot(0);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
// Verify that the monomorphic map is the one we expect.
Map number_map = ReadOnlyRoots(heap).heap_number_map();
CHECK_EQ(number_map, nexus.GetFirstMap());
// Now go polymorphic on o.
CompileRun("f(o)");
CHECK_EQ(POLYMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
MapHandles maps;
nexus.ExtractMaps(&maps);
@ -609,7 +611,7 @@ TEST(VectorLoadICOnSmi) {
// The degree of polymorphism doesn't change.
CompileRun("f(100)");
CHECK_EQ(POLYMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
MapHandles maps2;
nexus.ExtractMaps(&maps2);
CHECK_EQ(2, maps2.size());
@ -788,7 +790,7 @@ TEST(VectorStoreICBasic) {
CHECK_EQ(1, helper.slot_count());
FeedbackSlot slot(0);
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
}
TEST(StoreOwnIC) {
@ -816,7 +818,7 @@ TEST(StoreOwnIC) {
CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLiteral);
CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreOwnNamed);
FeedbackNexus nexus(feedback_vector, helper.slot(1));
CHECK_EQ(MONOMORPHIC, nexus.ic_state());
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
}
} // namespace