[ic] Remove the check for fast prototypes in LoadIC_Uninitialized
When handling load named properties (without feedback vectors) we used to miss to runtimes if the prototypes aren't set. This was because we wanted to give the prototype a chance to become fast, since most prototypes start in slow mode but move to fast after the initial setup. Though this check is not really useful when we don't have feedback vectors, and once feedback vectors are allocated we will turn the prototypes fast anyway. Bug: v8:8394, v8:8860 Change-Id: Ib2247e5e921f6375bda65310560ac832fd0339bf Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1561316 Commit-Queue: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#60818}
This commit is contained in:
parent
45df2e8a10
commit
d14ed12e56
@ -2616,46 +2616,15 @@ void AccessorAssembler::LoadIC_Noninlined(const LoadICParameters* p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(8860): This check is only required so we can make prototypes fast on
|
|
||||||
// the first load. This is not really useful when there is no feedback vector
|
|
||||||
// and may not be important when lazily allocating feedback vectors. Once lazy
|
|
||||||
// allocation of feedback vectors has landed try to eliminate this check.
|
|
||||||
void AccessorAssembler::BranchIfPrototypeShouldbeFast(Node* receiver_map,
|
|
||||||
Label* prototype_not_fast,
|
|
||||||
Label* prototype_fast) {
|
|
||||||
VARIABLE(var_map, MachineRepresentation::kTagged);
|
|
||||||
var_map.Bind(receiver_map);
|
|
||||||
Label loop_body(this, &var_map);
|
|
||||||
Goto(&loop_body);
|
|
||||||
|
|
||||||
BIND(&loop_body);
|
|
||||||
{
|
|
||||||
Node* map = var_map.value();
|
|
||||||
Node* prototype = LoadMapPrototype(map);
|
|
||||||
GotoIf(IsNull(prototype), prototype_fast);
|
|
||||||
TNode<PrototypeInfo> proto_info =
|
|
||||||
LoadMapPrototypeInfo(receiver_map, prototype_not_fast);
|
|
||||||
GotoIf(IsNull(prototype), prototype_not_fast);
|
|
||||||
TNode<Uint32T> flags =
|
|
||||||
LoadObjectField<Uint32T>(proto_info, PrototypeInfo::kBitFieldOffset);
|
|
||||||
GotoIf(Word32Equal(flags, Uint32Constant(0)), prototype_not_fast);
|
|
||||||
|
|
||||||
Node* prototype_map = LoadMap(prototype);
|
|
||||||
var_map.Bind(prototype_map);
|
|
||||||
Goto(&loop_body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) {
|
void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) {
|
||||||
Label miss(this, Label::kDeferred),
|
Label miss(this, Label::kDeferred),
|
||||||
check_if_fast_prototype(this, Label::kDeferred),
|
|
||||||
check_function_prototype(this);
|
check_function_prototype(this);
|
||||||
Node* receiver = p->receiver;
|
Node* receiver = p->receiver;
|
||||||
GotoIf(TaggedIsSmi(receiver), &miss);
|
GotoIf(TaggedIsSmi(receiver), &miss);
|
||||||
Node* receiver_map = LoadMap(receiver);
|
Node* receiver_map = LoadMap(receiver);
|
||||||
Node* instance_type = LoadMapInstanceType(receiver_map);
|
Node* instance_type = LoadMapInstanceType(receiver_map);
|
||||||
|
|
||||||
GotoIf(IsUndefined(p->vector), &check_if_fast_prototype);
|
GotoIf(IsUndefined(p->vector), &check_function_prototype);
|
||||||
// Optimistically write the state transition to the vector.
|
// Optimistically write the state transition to the vector.
|
||||||
StoreFeedbackVectorSlot(p->vector, p->slot,
|
StoreFeedbackVectorSlot(p->vector, p->slot,
|
||||||
LoadRoot(RootIndex::kpremonomorphic_symbol),
|
LoadRoot(RootIndex::kpremonomorphic_symbol),
|
||||||
@ -2664,12 +2633,6 @@ void AccessorAssembler::LoadIC_Uninitialized(const LoadICParameters* p) {
|
|||||||
kTaggedSize, SMI_PARAMETERS);
|
kTaggedSize, SMI_PARAMETERS);
|
||||||
Goto(&check_function_prototype);
|
Goto(&check_function_prototype);
|
||||||
|
|
||||||
BIND(&check_if_fast_prototype);
|
|
||||||
{
|
|
||||||
BranchIfPrototypeShouldbeFast(receiver_map, &miss,
|
|
||||||
&check_function_prototype);
|
|
||||||
}
|
|
||||||
|
|
||||||
BIND(&check_function_prototype);
|
BIND(&check_function_prototype);
|
||||||
{
|
{
|
||||||
// Special case for Function.prototype load, because it's very common
|
// Special case for Function.prototype load, because it's very common
|
||||||
|
@ -296,10 +296,6 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler {
|
|||||||
Representation representation, Node* value,
|
Representation representation, Node* value,
|
||||||
Label* bailout);
|
Label* bailout);
|
||||||
|
|
||||||
void BranchIfPrototypeShouldbeFast(Node* receiver_map,
|
|
||||||
Label* prototype_not_fast,
|
|
||||||
Label* prototype_fast);
|
|
||||||
|
|
||||||
// Extends properties backing store by JSObject::kFieldsAdded elements,
|
// Extends properties backing store by JSObject::kFieldsAdded elements,
|
||||||
// returns updated properties backing store.
|
// returns updated properties backing store.
|
||||||
Node* ExtendPropertiesBackingStore(Node* object, Node* index);
|
Node* ExtendPropertiesBackingStore(Node* object, Node* index);
|
||||||
|
Loading…
Reference in New Issue
Block a user