Commit 9188d549 authored by Mythri A's avatar Mythri A Committed by Commit Bot

[ic] Decouple transitions from KeyedAccessStoreMode

KeyedAccessStoreMode is used when creating store handlers to determine
which cases to handle (ex: handle cow, grow) and hence choose an
approriate builtin. It is also used to specify elements kind transitions
which is used when computing ic transitions. The store mode and the
transition mode are independent of each other and it would be cleaner to
use different enums to represent them. This also reduces the total number
of cases in each enum.

Change-Id: I96aeff7a765b312b8088e831776743c67c533bd9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1619751Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Mythri Alle <mythria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61729}
parent 45bfa681
......@@ -243,17 +243,17 @@ TF_BUILTIN(ElementsTransitionAndStore_Standard, HandlerBuiltinsAssembler) {
TF_BUILTIN(ElementsTransitionAndStore_GrowNoTransitionHandleCOW,
HandlerBuiltinsAssembler) {
Generate_ElementsTransitionAndStore(STORE_AND_GROW_NO_TRANSITION_HANDLE_COW);
Generate_ElementsTransitionAndStore(STORE_AND_GROW_HANDLE_COW);
}
TF_BUILTIN(ElementsTransitionAndStore_NoTransitionIgnoreOOB,
HandlerBuiltinsAssembler) {
Generate_ElementsTransitionAndStore(STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS);
Generate_ElementsTransitionAndStore(STORE_IGNORE_OUT_OF_BOUNDS);
}
TF_BUILTIN(ElementsTransitionAndStore_NoTransitionHandleCOW,
HandlerBuiltinsAssembler) {
Generate_ElementsTransitionAndStore(STORE_NO_TRANSITION_HANDLE_COW);
Generate_ElementsTransitionAndStore(STORE_HANDLE_COW);
}
// All elements kinds handled by EmitElementStore. Specifically, this includes
......@@ -353,15 +353,15 @@ TF_BUILTIN(StoreFastElementIC_Standard, HandlerBuiltinsAssembler) {
TF_BUILTIN(StoreFastElementIC_GrowNoTransitionHandleCOW,
HandlerBuiltinsAssembler) {
Generate_StoreFastElementIC(STORE_AND_GROW_NO_TRANSITION_HANDLE_COW);
Generate_StoreFastElementIC(STORE_AND_GROW_HANDLE_COW);
}
TF_BUILTIN(StoreFastElementIC_NoTransitionIgnoreOOB, HandlerBuiltinsAssembler) {
Generate_StoreFastElementIC(STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS);
Generate_StoreFastElementIC(STORE_IGNORE_OUT_OF_BOUNDS);
}
TF_BUILTIN(StoreFastElementIC_NoTransitionHandleCOW, HandlerBuiltinsAssembler) {
Generate_StoreFastElementIC(STORE_NO_TRANSITION_HANDLE_COW);
Generate_StoreFastElementIC(STORE_HANDLE_COW);
}
TF_BUILTIN(LoadGlobalIC_Slow, CodeStubAssembler) {
......
......@@ -104,15 +104,15 @@ Callable CodeFactory::KeyedStoreIC_SloppyArguments(Isolate* isolate,
case STANDARD_STORE:
builtin_index = Builtins::kKeyedStoreIC_SloppyArguments_Standard;
break;
case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
case STORE_AND_GROW_HANDLE_COW:
builtin_index =
Builtins::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW;
break;
case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
case STORE_IGNORE_OUT_OF_BOUNDS:
builtin_index =
Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB;
break;
case STORE_NO_TRANSITION_HANDLE_COW:
case STORE_HANDLE_COW:
builtin_index =
Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW;
break;
......@@ -129,13 +129,13 @@ Callable CodeFactory::KeyedStoreIC_Slow(Isolate* isolate,
case STANDARD_STORE:
builtin_index = Builtins::kKeyedStoreIC_Slow_Standard;
break;
case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
case STORE_AND_GROW_HANDLE_COW:
builtin_index = Builtins::kKeyedStoreIC_Slow_GrowNoTransitionHandleCOW;
break;
case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
case STORE_IGNORE_OUT_OF_BOUNDS:
builtin_index = Builtins::kKeyedStoreIC_Slow_NoTransitionIgnoreOOB;
break;
case STORE_NO_TRANSITION_HANDLE_COW:
case STORE_HANDLE_COW:
builtin_index = Builtins::kKeyedStoreIC_Slow_NoTransitionHandleCOW;
break;
default:
......@@ -151,15 +151,15 @@ Callable CodeFactory::StoreInArrayLiteralIC_Slow(Isolate* isolate,
case STANDARD_STORE:
builtin_index = Builtins::kStoreInArrayLiteralIC_Slow_Standard;
break;
case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
case STORE_AND_GROW_HANDLE_COW:
builtin_index =
Builtins::kStoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW;
break;
case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
case STORE_IGNORE_OUT_OF_BOUNDS:
builtin_index =
Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB;
break;
case STORE_NO_TRANSITION_HANDLE_COW:
case STORE_HANDLE_COW:
builtin_index =
Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionHandleCOW;
break;
......@@ -176,15 +176,15 @@ Callable CodeFactory::ElementsTransitionAndStore(Isolate* isolate,
case STANDARD_STORE:
builtin_index = Builtins::kElementsTransitionAndStore_Standard;
break;
case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
case STORE_AND_GROW_HANDLE_COW:
builtin_index =
Builtins::kElementsTransitionAndStore_GrowNoTransitionHandleCOW;
break;
case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
case STORE_IGNORE_OUT_OF_BOUNDS:
builtin_index =
Builtins::kElementsTransitionAndStore_NoTransitionIgnoreOOB;
break;
case STORE_NO_TRANSITION_HANDLE_COW:
case STORE_HANDLE_COW:
builtin_index =
Builtins::kElementsTransitionAndStore_NoTransitionHandleCOW;
break;
......@@ -201,13 +201,13 @@ Callable CodeFactory::StoreFastElementIC(Isolate* isolate,
case STANDARD_STORE:
builtin_index = Builtins::kStoreFastElementIC_Standard;
break;
case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
case STORE_AND_GROW_HANDLE_COW:
builtin_index = Builtins::kStoreFastElementIC_GrowNoTransitionHandleCOW;
break;
case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
case STORE_IGNORE_OUT_OF_BOUNDS:
builtin_index = Builtins::kStoreFastElementIC_NoTransitionIgnoreOOB;
break;
case STORE_NO_TRANSITION_HANDLE_COW:
case STORE_HANDLE_COW:
builtin_index = Builtins::kStoreFastElementIC_NoTransitionHandleCOW;
break;
default:
......
......@@ -10609,7 +10609,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
// Bounds check.
TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(object));
if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
if (store_mode == STORE_IGNORE_OUT_OF_BOUNDS) {
// Skip the store if we write beyond the length or
// to a property with a negative integer index.
GotoIfNot(UintPtrLessThan(intptr_key, length), &done);
......
......@@ -2618,7 +2618,7 @@ JSNativeContextSpecialization::BuildElementAccess(
}
if (load_mode == LOAD_IGNORE_OUT_OF_BOUNDS ||
store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
store_mode == STORE_IGNORE_OUT_OF_BOUNDS) {
// Only check that the {index} is in SignedSmall range. We do the actual
// bounds check below and just skip the property access if it's out of
// bounds for the {receiver}.
......@@ -2702,7 +2702,7 @@ JSNativeContextSpecialization::BuildElementAccess(
}
// Check if we can skip the out-of-bounds store.
if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
if (store_mode == STORE_IGNORE_OUT_OF_BOUNDS) {
Node* check =
graph()->NewNode(simplified()->NumberLessThan(), index, length);
Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
......@@ -2995,7 +2995,7 @@ JSNativeContextSpecialization::BuildElementAccess(
// Ensure that copy-on-write backing store is writable.
if (IsSmiOrObjectElementsKind(elements_kind) &&
store_mode == STORE_NO_TRANSITION_HANDLE_COW) {
store_mode == STORE_HANDLE_COW) {
elements = effect =
graph()->NewNode(simplified()->EnsureWritableFastElements(),
receiver, elements, effect, control);
......@@ -3037,7 +3037,7 @@ JSNativeContextSpecialization::BuildElementAccess(
// If we didn't grow {elements}, it might still be COW, in which case we
// copy it now.
if (IsSmiOrObjectElementsKind(elements_kind) &&
store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW) {
store_mode == STORE_AND_GROW_HANDLE_COW) {
elements = effect =
graph()->NewNode(simplified()->EnsureWritableFastElements(),
receiver, elements, effect, control);
......
......@@ -1153,19 +1153,19 @@ KeyedAccessStoreMode KeyedAccessStoreModeForBuiltin(int builtin_index) {
case Builtins::kKeyedStoreIC_Slow_GrowNoTransitionHandleCOW:
case Builtins::kStoreFastElementIC_GrowNoTransitionHandleCOW:
case Builtins::kElementsTransitionAndStore_GrowNoTransitionHandleCOW:
return STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
return STORE_AND_GROW_HANDLE_COW;
case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB:
case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB:
case Builtins::kKeyedStoreIC_Slow_NoTransitionIgnoreOOB:
case Builtins::kStoreFastElementIC_NoTransitionIgnoreOOB:
case Builtins::kElementsTransitionAndStore_NoTransitionIgnoreOOB:
return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS;
return STORE_IGNORE_OUT_OF_BOUNDS;
case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW:
case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionHandleCOW:
case Builtins::kKeyedStoreIC_Slow_NoTransitionHandleCOW:
case Builtins::kStoreFastElementIC_NoTransitionHandleCOW:
case Builtins::kElementsTransitionAndStore_NoTransitionHandleCOW:
return STORE_NO_TRANSITION_HANDLE_COW;
return STORE_HANDLE_COW;
default:
UNREACHABLE();
}
......
......@@ -1504,55 +1504,20 @@ enum KeyedAccessLoadMode {
enum KeyedAccessStoreMode {
STANDARD_STORE,
STORE_TRANSITION_TO_OBJECT,
STORE_TRANSITION_TO_DOUBLE,
STORE_AND_GROW_NO_TRANSITION_HANDLE_COW,
STORE_AND_GROW_TRANSITION_TO_OBJECT,
STORE_AND_GROW_TRANSITION_TO_DOUBLE,
STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
STORE_NO_TRANSITION_HANDLE_COW
STORE_AND_GROW_HANDLE_COW,
STORE_IGNORE_OUT_OF_BOUNDS,
STORE_HANDLE_COW
};
enum MutableMode { MUTABLE, IMMUTABLE };
static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
return store_mode == STORE_TRANSITION_TO_OBJECT ||
store_mode == STORE_TRANSITION_TO_DOUBLE ||
store_mode == STORE_AND_GROW_TRANSITION_TO_OBJECT ||
store_mode == STORE_AND_GROW_TRANSITION_TO_DOUBLE;
}
static inline bool IsCOWHandlingStoreMode(KeyedAccessStoreMode store_mode) {
return store_mode == STORE_NO_TRANSITION_HANDLE_COW ||
store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
}
static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
KeyedAccessStoreMode store_mode, bool receiver_was_cow) {
switch (store_mode) {
case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
case STORE_AND_GROW_TRANSITION_TO_OBJECT:
case STORE_AND_GROW_TRANSITION_TO_DOUBLE:
store_mode = STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
break;
case STANDARD_STORE:
case STORE_TRANSITION_TO_OBJECT:
case STORE_TRANSITION_TO_DOUBLE:
store_mode =
receiver_was_cow ? STORE_NO_TRANSITION_HANDLE_COW : STANDARD_STORE;
break;
case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
case STORE_NO_TRANSITION_HANDLE_COW:
break;
}
DCHECK(!IsTransitionStoreMode(store_mode));
DCHECK_IMPLIES(receiver_was_cow, IsCOWHandlingStoreMode(store_mode));
return store_mode;
return store_mode == STORE_HANDLE_COW ||
store_mode == STORE_AND_GROW_HANDLE_COW;
}
static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
return store_mode >= STORE_AND_GROW_NO_TRANSITION_HANDLE_COW &&
store_mode <= STORE_AND_GROW_TRANSITION_TO_DOUBLE;
return store_mode == STORE_AND_GROW_HANDLE_COW;
}
enum IcCheckType { ELEMENT, PROPERTY };
......
This diff is collapsed.
......@@ -334,6 +334,12 @@ enum KeyedStoreCheckMap { kDontCheckMap, kCheckMap };
enum KeyedStoreIncrementLength { kDontIncrementLength, kIncrementLength };
enum class TransitionMode {
kNoTransition,
kTransitionToDouble,
kTransitionToObject
};
class KeyedStoreIC : public StoreIC {
public:
KeyedAccessStoreMode GetKeyedAccessStoreMode() {
......@@ -351,7 +357,7 @@ class KeyedStoreIC : public StoreIC {
protected:
void UpdateStoreElement(Handle<Map> receiver_map,
KeyedAccessStoreMode store_mode,
bool receiver_was_cow);
TransitionMode transition_mode);
Handle<Code> slow_stub() const override {
return BUILTIN_CODE(isolate(), KeyedStoreIC_Slow);
......@@ -359,7 +365,7 @@ class KeyedStoreIC : public StoreIC {
private:
Handle<Map> ComputeTransitionedMap(Handle<Map> map,
KeyedAccessStoreMode store_mode);
TransitionMode transition_mode);
Handle<Object> StoreElementHandler(Handle<Map> receiver_map,
KeyedAccessStoreMode store_mode);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment