[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:
parent
4dab3a31f7
commit
f47eec071e
@ -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();
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
12
src/ic/ic.cc
12
src/ic/ic.cc
@ -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:
|
||||
|
@ -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(); }
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user