[ic] Deal with lookup result immediately when we find a property on a dictionary receiver
BUG=v8:6039 Change-Id: I69bae9ed49d91b0bc67a8e66e469d57ea7799cca Reviewed-on: https://chromium-review.googlesource.com/449793 Reviewed-by: Igor Sheludko <ishell@chromium.org> Commit-Queue: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#43584}
This commit is contained in:
parent
eb36a7dbcf
commit
6a0acc135e
@ -368,15 +368,26 @@ void AccessorAssembler::HandleLoadICProtoHandlerCase(
|
|||||||
Node* handler_flags = SmiUntag(smi_handler);
|
Node* handler_flags = SmiUntag(smi_handler);
|
||||||
|
|
||||||
Label check_prototypes(this);
|
Label check_prototypes(this);
|
||||||
GotoIfNot(
|
GotoIfNot(IsSetWord<LoadHandler::LookupOnReceiverBits>(handler_flags),
|
||||||
IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>(handler_flags),
|
&check_prototypes);
|
||||||
&check_prototypes);
|
|
||||||
{
|
{
|
||||||
CSA_ASSERT(this, Word32BinaryNot(
|
CSA_ASSERT(this, Word32BinaryNot(
|
||||||
HasInstanceType(p->receiver, JS_GLOBAL_OBJECT_TYPE)));
|
HasInstanceType(p->receiver, JS_GLOBAL_OBJECT_TYPE)));
|
||||||
// We have a dictionary receiver, do a negative lookup check.
|
Node* properties = LoadProperties(p->receiver);
|
||||||
NameDictionaryNegativeLookup(p->receiver, p->name, miss);
|
Variable var_name_index(this, MachineType::PointerRepresentation());
|
||||||
Goto(&check_prototypes);
|
Label found(this, &var_name_index);
|
||||||
|
NameDictionaryLookup<NameDictionary>(properties, p->name, &found,
|
||||||
|
&var_name_index, &check_prototypes);
|
||||||
|
Bind(&found);
|
||||||
|
{
|
||||||
|
Variable var_details(this, MachineRepresentation::kWord32);
|
||||||
|
Variable var_value(this, MachineRepresentation::kTagged);
|
||||||
|
LoadPropertyFromNameDictionary(properties, var_name_index.value(),
|
||||||
|
&var_details, &var_value);
|
||||||
|
Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(),
|
||||||
|
p->context, p->receiver, miss);
|
||||||
|
exit_point->Return(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bind(&check_prototypes);
|
Bind(&check_prototypes);
|
||||||
|
@ -52,22 +52,21 @@ Handle<Object> LoadHandler::EnableAccessCheckOnReceiver(
|
|||||||
return handle(Smi::FromInt(config), isolate);
|
return handle(Smi::FromInt(config), isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Object> LoadHandler::EnableNegativeLookupOnReceiver(
|
Handle<Object> LoadHandler::EnableLookupOnReceiver(Isolate* isolate,
|
||||||
Isolate* isolate, Handle<Object> smi_handler) {
|
Handle<Object> smi_handler) {
|
||||||
int config = Smi::cast(*smi_handler)->value();
|
int config = Smi::cast(*smi_handler)->value();
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Kind kind = KindBits::decode(config);
|
Kind kind = KindBits::decode(config);
|
||||||
DCHECK_NE(kForElements, kind);
|
DCHECK_NE(kForElements, kind);
|
||||||
#endif
|
#endif
|
||||||
config = DoNegativeLookupOnReceiverBits::update(config, true);
|
config = LookupOnReceiverBits::update(config, true);
|
||||||
return handle(Smi::FromInt(config), isolate);
|
return handle(Smi::FromInt(config), isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Object> LoadHandler::LoadNonExistent(
|
Handle<Object> LoadHandler::LoadNonExistent(Isolate* isolate,
|
||||||
Isolate* isolate, bool do_negative_lookup_on_receiver) {
|
bool do_lookup_on_receiver) {
|
||||||
int config =
|
int config = KindBits::encode(kForNonExistent) |
|
||||||
KindBits::encode(kForNonExistent) |
|
LookupOnReceiverBits::encode(do_lookup_on_receiver);
|
||||||
DoNegativeLookupOnReceiverBits::encode(do_negative_lookup_on_receiver);
|
|
||||||
return handle(Smi::FromInt(config), isolate);
|
return handle(Smi::FromInt(config), isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,10 +31,11 @@ class LoadHandler {
|
|||||||
class DoAccessCheckOnReceiverBits
|
class DoAccessCheckOnReceiverBits
|
||||||
: public BitField<bool, KindBits::kNext, 1> {};
|
: public BitField<bool, KindBits::kNext, 1> {};
|
||||||
|
|
||||||
// Defines whether negative lookup check should be done on receiver object.
|
// Defines whether a lookup should be done on receiver object before
|
||||||
// Applicable to kForFields, kForConstants and kForNonExistent kinds only when
|
// proceeding to the prototype chain. Applicable to kForFields, kForConstants
|
||||||
// loading value from prototype chain. Ignored when loading from holder.
|
// and kForNonExistent kinds only when loading value from prototype chain.
|
||||||
class DoNegativeLookupOnReceiverBits
|
// Ignored when loading from holder.
|
||||||
|
class LookupOnReceiverBits
|
||||||
: public BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1> {};
|
: public BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1> {};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -42,7 +43,7 @@ class LoadHandler {
|
|||||||
//
|
//
|
||||||
|
|
||||||
class IsAccessorInfoBits
|
class IsAccessorInfoBits
|
||||||
: public BitField<bool, DoNegativeLookupOnReceiverBits::kNext, 1> {};
|
: public BitField<bool, LookupOnReceiverBits::kNext, 1> {};
|
||||||
// Index of a value entry in the descriptor array.
|
// Index of a value entry in the descriptor array.
|
||||||
class DescriptorBits : public BitField<unsigned, IsAccessorInfoBits::kNext,
|
class DescriptorBits : public BitField<unsigned, IsAccessorInfoBits::kNext,
|
||||||
kDescriptorIndexBitCount> {};
|
kDescriptorIndexBitCount> {};
|
||||||
@ -52,8 +53,8 @@ class LoadHandler {
|
|||||||
//
|
//
|
||||||
// Encoding when KindBits contains kForFields.
|
// Encoding when KindBits contains kForFields.
|
||||||
//
|
//
|
||||||
class IsInobjectBits
|
class IsInobjectBits : public BitField<bool, LookupOnReceiverBits::kNext, 1> {
|
||||||
: public BitField<bool, DoNegativeLookupOnReceiverBits::kNext, 1> {};
|
};
|
||||||
class IsDoubleBits : public BitField<bool, IsInobjectBits::kNext, 1> {};
|
class IsDoubleBits : public BitField<bool, IsInobjectBits::kNext, 1> {};
|
||||||
// +1 here is to cover all possible JSObject header sizes.
|
// +1 here is to cover all possible JSObject header sizes.
|
||||||
class FieldOffsetBits
|
class FieldOffsetBits
|
||||||
@ -105,15 +106,15 @@ class LoadHandler {
|
|||||||
static inline Handle<Object> EnableAccessCheckOnReceiver(
|
static inline Handle<Object> EnableAccessCheckOnReceiver(
|
||||||
Isolate* isolate, Handle<Object> smi_handler);
|
Isolate* isolate, Handle<Object> smi_handler);
|
||||||
|
|
||||||
// Sets DoNegativeLookupOnReceiverBits in given Smi-handler. The receiver
|
// Sets LookupOnReceiverBits in given Smi-handler. The receiver
|
||||||
// check is a part of a prototype chain check.
|
// check is a part of a prototype chain check.
|
||||||
static inline Handle<Object> EnableNegativeLookupOnReceiver(
|
static inline Handle<Object> EnableLookupOnReceiver(
|
||||||
Isolate* isolate, Handle<Object> smi_handler);
|
Isolate* isolate, Handle<Object> smi_handler);
|
||||||
|
|
||||||
// Creates a Smi-handler for loading a non-existent property. Works only as
|
// Creates a Smi-handler for loading a non-existent property. Works only as
|
||||||
// a part of prototype chain check.
|
// a part of prototype chain check.
|
||||||
static inline Handle<Object> LoadNonExistent(
|
static inline Handle<Object> LoadNonExistent(Isolate* isolate,
|
||||||
Isolate* isolate, bool do_negative_lookup_on_receiver);
|
bool do_lookup_on_receiver);
|
||||||
|
|
||||||
// Creates a Smi-handler for loading an element.
|
// Creates a Smi-handler for loading an element.
|
||||||
static inline Handle<Object> LoadElement(Isolate* isolate,
|
static inline Handle<Object> LoadElement(Isolate* isolate,
|
||||||
|
@ -979,8 +979,7 @@ Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
|
|||||||
LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler);
|
LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler);
|
||||||
} else if (receiver_map->is_dictionary_map() &&
|
} else if (receiver_map->is_dictionary_map() &&
|
||||||
!receiver_map->IsJSGlobalObjectMap()) {
|
!receiver_map->IsJSGlobalObjectMap()) {
|
||||||
smi_handler =
|
smi_handler = LoadHandler::EnableLookupOnReceiver(isolate(), smi_handler);
|
||||||
LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Cell> validity_cell =
|
Handle<Cell> validity_cell =
|
||||||
|
Loading…
Reference in New Issue
Block a user