Commit 7b59e3d7 authored by verwaest's avatar verwaest Committed by Commit bot

[runtime] Minor tweaks to LookupIterator for performance

BUG=

Review URL: https://codereview.chromium.org/1702443002

Cr-Commit-Position: refs/heads/master@{#34024}
parent b543c40d
......@@ -1406,9 +1406,10 @@ MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value,
JSReceiver::StoreFromKeyed store_mode) {
// Disable ICs for non-JSObjects for now.
Handle<Object> receiver = it->GetReceiver();
if (!receiver->IsJSObject()) return false;
DCHECK(!Handle<JSObject>::cast(receiver)->map()->is_deprecated());
Handle<Object> object = it->GetReceiver();
if (!object->IsJSObject()) return false;
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
DCHECK(!receiver->map()->is_deprecated());
for (; it->IsFound(); it->Next()) {
switch (it->state()) {
......@@ -1448,21 +1449,23 @@ bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value,
// Receiver != holder.
if (receiver->IsJSGlobalProxy()) {
PrototypeIterator iter(it->isolate(),
Handle<JSGlobalProxy>::cast(receiver));
PrototypeIterator iter(it->isolate(), receiver);
return it->GetHolder<Object>().is_identical_to(
PrototypeIterator::GetCurrent(iter));
}
if (it->HolderIsReceiverOrHiddenPrototype()) return false;
it->PrepareTransitionToDataProperty(value, NONE, store_mode);
if (it->ExtendingNonExtensible(receiver)) return false;
it->PrepareTransitionToDataProperty(receiver, value, NONE, store_mode);
return it->IsCacheableTransition();
}
}
}
it->PrepareTransitionToDataProperty(value, NONE, store_mode);
receiver = it->GetStoreTarget();
if (it->ExtendingNonExtensible(receiver)) return false;
it->PrepareTransitionToDataProperty(receiver, value, NONE, store_mode);
return it->IsCacheableTransition();
}
......
......@@ -122,9 +122,10 @@ Handle<Map> LookupIterator::GetReceiverMap() const {
Handle<JSObject> LookupIterator::GetStoreTarget() const {
if (receiver_->IsJSGlobalProxy()) {
PrototypeIterator iter(isolate(), Handle<JSGlobalProxy>::cast(receiver_));
if (iter.IsAtEnd()) return Handle<JSGlobalProxy>::cast(receiver_);
return PrototypeIterator::GetCurrent<JSGlobalObject>(iter);
Object* prototype = JSGlobalProxy::cast(*receiver_)->map()->prototype();
if (!prototype->IsNull()) {
return handle(JSGlobalObject::cast(prototype), isolate_);
}
}
return Handle<JSObject>::cast(receiver_);
}
......@@ -232,25 +233,18 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
#endif
}
// Can only be called when the receiver is a JSObject. JSProxy has to be handled
// via a trap. Adding properties to primitive values is not observable.
void LookupIterator::PrepareTransitionToDataProperty(
Handle<Object> value, PropertyAttributes attributes,
Object::StoreFromKeyed store_mode) {
Handle<JSObject> receiver, Handle<Object> value,
PropertyAttributes attributes, Object::StoreFromKeyed store_mode) {
DCHECK(receiver.is_identical_to(GetStoreTarget()));
if (state_ == TRANSITION) return;
DCHECK(state_ != LookupIterator::ACCESSOR ||
(GetAccessors()->IsAccessorInfo() &&
AccessorInfo::cast(*GetAccessors())->is_special_data_property()));
DCHECK_NE(INTEGER_INDEXED_EXOTIC, state_);
DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype());
// Can only be called when the receiver is a JSObject. JSProxy has to be
// handled via a trap. Adding properties to primitive values is not
// observable.
Handle<JSObject> receiver = GetStoreTarget();
if (!isolate()->IsInternallyUsedPropertyName(name()) &&
!receiver->map()->is_extensible()) {
return;
}
auto transition = Map::TransitionToDataProperty(
handle(receiver->map(), isolate_), name_, value, attributes, store_mode);
......@@ -270,11 +264,11 @@ void LookupIterator::PrepareTransitionToDataProperty(
}
}
void LookupIterator::ApplyTransitionToDataProperty() {
void LookupIterator::ApplyTransitionToDataProperty(Handle<JSObject> receiver) {
DCHECK_EQ(TRANSITION, state_);
Handle<JSObject> receiver = GetStoreTarget();
DCHECK(receiver.is_identical_to(GetStoreTarget()));
if (receiver->IsJSGlobalObject()) return;
holder_ = receiver;
Handle<Map> transition = transition_map();
......
......@@ -210,17 +210,23 @@ class LookupIterator final BASE_EMBEDDED {
bool HasAccess() const;
/* PROPERTY */
bool ExtendingNonExtensible(Handle<JSObject> receiver) {
DCHECK(receiver.is_identical_to(GetStoreTarget()));
return !receiver->map()->is_extensible() &&
(IsElement() || !isolate_->IsInternallyUsedPropertyName(name_));
}
void PrepareForDataProperty(Handle<Object> value);
void PrepareTransitionToDataProperty(Handle<Object> value,
void PrepareTransitionToDataProperty(Handle<JSObject> receiver,
Handle<Object> value,
PropertyAttributes attributes,
Object::StoreFromKeyed store_mode);
bool IsCacheableTransition() {
if (state_ != TRANSITION) return false;
DCHECK_EQ(TRANSITION, state_);
return transition_->IsPropertyCell() ||
(!transition_map()->is_dictionary_map() &&
transition_map()->GetBackPointer()->IsMap());
}
void ApplyTransitionToDataProperty();
void ApplyTransitionToDataProperty(Handle<JSObject> receiver);
void ReconfigureDataProperty(Handle<Object> value,
PropertyAttributes attributes);
void Delete();
......
......@@ -4606,8 +4606,7 @@ Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
Isolate* isolate = it->isolate();
if (!receiver->map()->is_extensible() &&
(it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name()))) {
if (it->ExtendingNonExtensible(receiver)) {
RETURN_FAILURE(
isolate, should_throw,
NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName()));
......@@ -4640,9 +4639,10 @@ Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
} else {
// Migrate to the most up-to-date map that will be able to store |value|
// under it->name() with |attributes|.
it->PrepareTransitionToDataProperty(value, attributes, store_mode);
it->PrepareTransitionToDataProperty(receiver, value, attributes,
store_mode);
DCHECK_EQ(LookupIterator::TRANSITION, it->state());
it->ApplyTransitionToDataProperty();
it->ApplyTransitionToDataProperty(receiver);
// TODO(verwaest): Encapsulate dictionary handling better.
if (receiver->map()->is_dictionary_map()) {
......
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