| Index: src/lookup.cc
|
| diff --git a/src/lookup.cc b/src/lookup.cc
|
| index c3e0fdb8a6845a15c61b4ad3cd2c2a86b722125e..3943bf3b98f12d91c813ee82e9a7825908efba30 100644
|
| --- a/src/lookup.cc
|
| +++ b/src/lookup.cc
|
| @@ -5,6 +5,7 @@
|
| #include "src/v8.h"
|
|
|
| #include "src/bootstrapper.h"
|
| +#include "src/deoptimizer.h"
|
| #include "src/lookup.h"
|
| #include "src/lookup-inl.h"
|
|
|
| @@ -109,6 +110,14 @@ bool LookupIterator::HasProperty() {
|
| }
|
|
|
|
|
| +void LookupIterator::ReloadPropertyInformation() {
|
| + state_ = BEFORE_PROPERTY;
|
| + state_ = LookupInHolder(*holder_map_);
|
| + DCHECK(IsFound());
|
| + HasProperty();
|
| +}
|
| +
|
| +
|
| void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
|
| DCHECK(has_property_);
|
| DCHECK(HolderIsReceiverOrHiddenPrototype());
|
| @@ -116,13 +125,7 @@ void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
|
| holder_map_ =
|
| Map::PrepareForDataProperty(holder_map_, descriptor_number(), value);
|
| JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_);
|
| - // Reload property information.
|
| - if (holder_map_->is_dictionary_map()) {
|
| - property_encoding_ = DICTIONARY;
|
| - } else {
|
| - property_encoding_ = DESCRIPTOR;
|
| - }
|
| - CHECK(HasProperty());
|
| + ReloadPropertyInformation();
|
| }
|
|
|
|
|
| @@ -137,17 +140,12 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
|
| JSObject::MigrateToMap(holder, holder_map_);
|
| }
|
|
|
| - // Reload property information and update the descriptor if in dictionary
|
| - // mode.
|
| if (holder_map_->is_dictionary_map()) {
|
| - property_encoding_ = DICTIONARY;
|
| PropertyDetails details(attributes, NORMAL, 0);
|
| JSObject::SetNormalizedProperty(holder, name(), value, details);
|
| - } else {
|
| - property_encoding_ = DESCRIPTOR;
|
| }
|
|
|
| - CHECK(HasProperty());
|
| + ReloadPropertyInformation();
|
| }
|
|
|
|
|
| @@ -172,12 +170,62 @@ void LookupIterator::TransitionToDataProperty(
|
| value, attributes, store_mode);
|
| JSObject::MigrateToMap(receiver, holder_map_);
|
|
|
| - // Reload the information.
|
| - state_ = NOT_FOUND;
|
| - configuration_ = CHECK_PROPERTY;
|
| - state_ = LookupInHolder(*holder_map_);
|
| - DCHECK(IsFound());
|
| - HasProperty();
|
| + ReloadPropertyInformation();
|
| +}
|
| +
|
| +
|
| +void LookupIterator::TransitionToAccessorProperty(
|
| + AccessorComponent component, Handle<Object> accessor,
|
| + PropertyAttributes attributes) {
|
| + DCHECK(!accessor->IsNull());
|
| + // 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 = Handle<JSObject>::cast(GetReceiver());
|
| +
|
| + if (receiver->IsJSGlobalProxy()) {
|
| + PrototypeIterator iter(isolate(), receiver);
|
| + receiver =
|
| + Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
|
| + }
|
| +
|
| + maybe_holder_ = receiver;
|
| + holder_map_ = Map::TransitionToAccessorProperty(
|
| + handle(receiver->map()), name_, component, accessor, attributes);
|
| + JSObject::MigrateToMap(receiver, holder_map_);
|
| +
|
| + ReloadPropertyInformation();
|
| +
|
| + if (!holder_map_->is_dictionary_map()) return;
|
| +
|
| + // We have to deoptimize since accesses to data properties may have been
|
| + // inlined without a corresponding map-check.
|
| + if (holder_map_->IsGlobalObjectMap()) {
|
| + Deoptimizer::DeoptimizeGlobalObject(*receiver);
|
| + }
|
| +
|
| + // Install the accessor into the dictionary-mode object.
|
| + PropertyDetails details(attributes, CALLBACKS, 0);
|
| + Handle<AccessorPair> pair;
|
| + if (IsFound() && HasProperty() && property_kind() == ACCESSOR &&
|
| + GetAccessors()->IsAccessorPair()) {
|
| + pair = Handle<AccessorPair>::cast(GetAccessors());
|
| + // If the component and attributes are identical, nothing has to be done.
|
| + if (pair->get(component) == *accessor) {
|
| + if (property_details().attributes() == attributes) return;
|
| + } else {
|
| + pair = AccessorPair::Copy(pair);
|
| + pair->set(component, *accessor);
|
| + }
|
| + } else {
|
| + pair = isolate()->factory()->NewAccessorPair();
|
| + pair->set(component, *accessor);
|
| + }
|
| + JSObject::SetNormalizedProperty(receiver, name_, pair, details);
|
| +
|
| + JSObject::ReoptimizeIfPrototype(receiver);
|
| + holder_map_ = handle(receiver->map());
|
| + ReloadPropertyInformation();
|
| }
|
|
|
|
|
|
|