[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);
|
||||
|
||||
Label check_prototypes(this);
|
||||
GotoIfNot(
|
||||
IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>(handler_flags),
|
||||
&check_prototypes);
|
||||
GotoIfNot(IsSetWord<LoadHandler::LookupOnReceiverBits>(handler_flags),
|
||||
&check_prototypes);
|
||||
{
|
||||
CSA_ASSERT(this, Word32BinaryNot(
|
||||
HasInstanceType(p->receiver, JS_GLOBAL_OBJECT_TYPE)));
|
||||
// We have a dictionary receiver, do a negative lookup check.
|
||||
NameDictionaryNegativeLookup(p->receiver, p->name, miss);
|
||||
Goto(&check_prototypes);
|
||||
Node* properties = LoadProperties(p->receiver);
|
||||
Variable var_name_index(this, MachineType::PointerRepresentation());
|
||||
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);
|
||||
|
@ -52,22 +52,21 @@ Handle<Object> LoadHandler::EnableAccessCheckOnReceiver(
|
||||
return handle(Smi::FromInt(config), isolate);
|
||||
}
|
||||
|
||||
Handle<Object> LoadHandler::EnableNegativeLookupOnReceiver(
|
||||
Isolate* isolate, Handle<Object> smi_handler) {
|
||||
Handle<Object> LoadHandler::EnableLookupOnReceiver(Isolate* isolate,
|
||||
Handle<Object> smi_handler) {
|
||||
int config = Smi::cast(*smi_handler)->value();
|
||||
#ifdef DEBUG
|
||||
Kind kind = KindBits::decode(config);
|
||||
DCHECK_NE(kForElements, kind);
|
||||
#endif
|
||||
config = DoNegativeLookupOnReceiverBits::update(config, true);
|
||||
config = LookupOnReceiverBits::update(config, true);
|
||||
return handle(Smi::FromInt(config), isolate);
|
||||
}
|
||||
|
||||
Handle<Object> LoadHandler::LoadNonExistent(
|
||||
Isolate* isolate, bool do_negative_lookup_on_receiver) {
|
||||
int config =
|
||||
KindBits::encode(kForNonExistent) |
|
||||
DoNegativeLookupOnReceiverBits::encode(do_negative_lookup_on_receiver);
|
||||
Handle<Object> LoadHandler::LoadNonExistent(Isolate* isolate,
|
||||
bool do_lookup_on_receiver) {
|
||||
int config = KindBits::encode(kForNonExistent) |
|
||||
LookupOnReceiverBits::encode(do_lookup_on_receiver);
|
||||
return handle(Smi::FromInt(config), isolate);
|
||||
}
|
||||
|
||||
|
@ -31,10 +31,11 @@ class LoadHandler {
|
||||
class DoAccessCheckOnReceiverBits
|
||||
: public BitField<bool, KindBits::kNext, 1> {};
|
||||
|
||||
// Defines whether negative lookup check should be done on receiver object.
|
||||
// Applicable to kForFields, kForConstants and kForNonExistent kinds only when
|
||||
// loading value from prototype chain. Ignored when loading from holder.
|
||||
class DoNegativeLookupOnReceiverBits
|
||||
// Defines whether a lookup should be done on receiver object before
|
||||
// proceeding to the prototype chain. Applicable to kForFields, kForConstants
|
||||
// and kForNonExistent kinds only when loading value from prototype chain.
|
||||
// Ignored when loading from holder.
|
||||
class LookupOnReceiverBits
|
||||
: public BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1> {};
|
||||
|
||||
//
|
||||
@ -42,7 +43,7 @@ class LoadHandler {
|
||||
//
|
||||
|
||||
class IsAccessorInfoBits
|
||||
: public BitField<bool, DoNegativeLookupOnReceiverBits::kNext, 1> {};
|
||||
: public BitField<bool, LookupOnReceiverBits::kNext, 1> {};
|
||||
// Index of a value entry in the descriptor array.
|
||||
class DescriptorBits : public BitField<unsigned, IsAccessorInfoBits::kNext,
|
||||
kDescriptorIndexBitCount> {};
|
||||
@ -52,8 +53,8 @@ class LoadHandler {
|
||||
//
|
||||
// Encoding when KindBits contains kForFields.
|
||||
//
|
||||
class IsInobjectBits
|
||||
: public BitField<bool, DoNegativeLookupOnReceiverBits::kNext, 1> {};
|
||||
class IsInobjectBits : public BitField<bool, LookupOnReceiverBits::kNext, 1> {
|
||||
};
|
||||
class IsDoubleBits : public BitField<bool, IsInobjectBits::kNext, 1> {};
|
||||
// +1 here is to cover all possible JSObject header sizes.
|
||||
class FieldOffsetBits
|
||||
@ -105,15 +106,15 @@ class LoadHandler {
|
||||
static inline Handle<Object> EnableAccessCheckOnReceiver(
|
||||
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.
|
||||
static inline Handle<Object> EnableNegativeLookupOnReceiver(
|
||||
static inline Handle<Object> EnableLookupOnReceiver(
|
||||
Isolate* isolate, Handle<Object> smi_handler);
|
||||
|
||||
// Creates a Smi-handler for loading a non-existent property. Works only as
|
||||
// a part of prototype chain check.
|
||||
static inline Handle<Object> LoadNonExistent(
|
||||
Isolate* isolate, bool do_negative_lookup_on_receiver);
|
||||
static inline Handle<Object> LoadNonExistent(Isolate* isolate,
|
||||
bool do_lookup_on_receiver);
|
||||
|
||||
// Creates a Smi-handler for loading an element.
|
||||
static inline Handle<Object> LoadElement(Isolate* isolate,
|
||||
|
@ -979,8 +979,7 @@ Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
|
||||
LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler);
|
||||
} else if (receiver_map->is_dictionary_map() &&
|
||||
!receiver_map->IsJSGlobalObjectMap()) {
|
||||
smi_handler =
|
||||
LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler);
|
||||
smi_handler = LoadHandler::EnableLookupOnReceiver(isolate(), smi_handler);
|
||||
}
|
||||
|
||||
Handle<Cell> validity_cell =
|
||||
|
Loading…
Reference in New Issue
Block a user