Revision: 23692
Author:   [email protected]
Date:     Thu Sep  4 12:28:13 2014 UTC
Log: Flatten property_kind into state. Add UNKNOWN as a state for dict-mode receivers

BUG=
[email protected]

Review URL: https://codereview.chromium.org/540903002
https://code.google.com/p/v8/source/detail?r=23692

Modified:
 /branches/bleeding_edge/src/accessors.cc
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ic/arm/handler-compiler-arm.cc
 /branches/bleeding_edge/src/ic/arm64/handler-compiler-arm64.cc
 /branches/bleeding_edge/src/ic/handler-compiler.cc
 /branches/bleeding_edge/src/ic/ia32/handler-compiler-ia32.cc
 /branches/bleeding_edge/src/ic/ic.cc
 /branches/bleeding_edge/src/ic/mips/handler-compiler-mips.cc
 /branches/bleeding_edge/src/ic/mips64/handler-compiler-mips64.cc
 /branches/bleeding_edge/src/ic/x64/handler-compiler-x64.cc
 /branches/bleeding_edge/src/ic/x87/handler-compiler-x87.cc
 /branches/bleeding_edge/src/lookup-inl.h
 /branches/bleeding_edge/src/lookup.cc
 /branches/bleeding_edge/src/lookup.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/src/accessors.cc    Mon Sep  1 09:11:44 2014 UTC
+++ /branches/bleeding_edge/src/accessors.cc    Thu Sep  4 12:28:13 2014 UTC
@@ -181,7 +181,7 @@
   if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) return;

   LookupIterator it(object, Utils::OpenHandle(*name));
-  CHECK(it.HasProperty());
+  CHECK_EQ(LookupIterator::ACCESSOR, it.state());
   DCHECK(it.HolderIsReceiverOrHiddenPrototype());
   Object::SetDataProperty(&it, value);
 }
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Wed Sep  3 14:05:55 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu Sep  4 12:28:13 2014 UTC
@@ -2488,7 +2488,7 @@
           LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
           CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
           // If the property is already there we skip it
-          if (it.IsFound() && it.HasProperty()) continue;
+          if (it.IsFound()) continue;
           HandleScope inner(isolate());
           DCHECK(!to->HasFastProperties());
           // Add to dictionary.
@@ -2516,7 +2516,7 @@
         Handle<Name> key(Name::cast(raw_key));
         LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
         CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
-        if (it.IsFound() && it.HasProperty()) continue;
+        if (it.IsFound()) continue;
         // Set the property.
         Handle<Object> value = Handle<Object>(properties->ValueAt(i),
                                               isolate());
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Thu Sep  4 12:25:57 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Thu Sep  4 12:28:13 2014 UTC
@@ -5297,21 +5297,17 @@
   }

   switch (it->state()) {
+    case LookupIterator::ACCESSOR:
     case LookupIterator::ACCESS_CHECK:
     case LookupIterator::INTERCEPTOR:
     case LookupIterator::NOT_FOUND:
       return kUseGeneric;
-    case LookupIterator::PROPERTY:
-      if (!it->HasProperty()) return kUseGeneric;
-      switch (it->property_kind()) {
-        case LookupIterator::DATA:
-          if (access_type == STORE && it->IsReadOnly()) return kUseGeneric;
-          return kUseCell;
-        case LookupIterator::ACCESSOR:
-          return kUseGeneric;
-      }
+    case LookupIterator::DATA:
+      if (access_type == STORE && it->IsReadOnly()) return kUseGeneric;
+      return kUseCell;
     case LookupIterator::JSPROXY:
     case LookupIterator::TRANSITION:
+    case LookupIterator::UNKNOWN:
       UNREACHABLE();
   }
   UNREACHABLE();
=======================================
--- /branches/bleeding_edge/src/ic/arm/handler-compiler-arm.cc Wed Sep 3 13:14:55 2014 UTC +++ /branches/bleeding_edge/src/ic/arm/handler-compiler-arm.cc Thu Sep 4 12:28:13 2014 UTC
@@ -709,8 +709,7 @@
       !holder().is_identical_to(it->GetHolder<JSObject>());
   bool must_preserve_receiver_reg =
       !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check);

   // Save necessary data before invoking an interceptor.
   // Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/arm64/handler-compiler-arm64.cc Wed Sep 3 13:14:55 2014 UTC +++ /branches/bleeding_edge/src/ic/arm64/handler-compiler-arm64.cc Thu Sep 4 12:28:13 2014 UTC
@@ -760,8 +760,7 @@
       !holder().is_identical_to(it->GetHolder<JSObject>());
   bool must_preserve_receiver_reg =
       !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check);

   // Save necessary data before invoking an interceptor.
   // Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/handler-compiler.cc Mon Aug 25 11:20:43 2014 UTC +++ /branches/bleeding_edge/src/ic/handler-compiler.cc Thu Sep 4 12:28:13 2014 UTC
@@ -225,22 +225,28 @@
   // So far the most popular follow ups for interceptor loads are FIELD and
   // ExecutableAccessorInfo, so inline only them. Other cases may be added
   // later.
-  bool inline_followup = it->state() == LookupIterator::PROPERTY;
-  if (inline_followup) {
-    switch (it->property_kind()) {
-      case LookupIterator::DATA:
-        inline_followup = it->property_details().type() == FIELD;
-        break;
-      case LookupIterator::ACCESSOR: {
-        Handle<Object> accessors = it->GetAccessors();
-        inline_followup = accessors->IsExecutableAccessorInfo();
-        if (!inline_followup) break;
-        Handle<ExecutableAccessorInfo> info =
-            Handle<ExecutableAccessorInfo>::cast(accessors);
-        inline_followup = info->getter() != NULL &&
-                          ExecutableAccessorInfo::IsCompatibleReceiverType(
-                              isolate(), info, type());
-      }
+  bool inline_followup = false;
+  switch (it->state()) {
+    case LookupIterator::TRANSITION:
+    case LookupIterator::UNKNOWN:
+      UNREACHABLE();
+    case LookupIterator::ACCESS_CHECK:
+    case LookupIterator::INTERCEPTOR:
+    case LookupIterator::JSPROXY:
+    case LookupIterator::NOT_FOUND:
+      break;
+    case LookupIterator::DATA:
+      inline_followup = it->property_details().type() == FIELD;
+      break;
+    case LookupIterator::ACCESSOR: {
+      Handle<Object> accessors = it->GetAccessors();
+      inline_followup = accessors->IsExecutableAccessorInfo();
+      if (!inline_followup) break;
+      Handle<ExecutableAccessorInfo> info =
+          Handle<ExecutableAccessorInfo>::cast(accessors);
+      inline_followup = info->getter() != NULL &&
+                        ExecutableAccessorInfo::IsCompatibleReceiverType(
+                            isolate(), info, type());
     }
   }

@@ -264,7 +270,14 @@
   set_holder(real_named_property_holder);
   Register reg = Frontend(interceptor_reg, it->name());

-  switch (it->property_kind()) {
+  switch (it->state()) {
+    case LookupIterator::ACCESS_CHECK:
+    case LookupIterator::INTERCEPTOR:
+    case LookupIterator::JSPROXY:
+    case LookupIterator::NOT_FOUND:
+    case LookupIterator::TRANSITION:
+    case LookupIterator::UNKNOWN:
+      UNREACHABLE();
     case LookupIterator::DATA: {
       DCHECK_EQ(FIELD, it->property_details().type());
       __ Move(receiver(), reg);
=======================================
--- /branches/bleeding_edge/src/ic/ia32/handler-compiler-ia32.cc Wed Sep 3 13:14:55 2014 UTC +++ /branches/bleeding_edge/src/ic/ia32/handler-compiler-ia32.cc Thu Sep 4 12:28:13 2014 UTC
@@ -699,8 +699,7 @@
       !holder().is_identical_to(it->GetHolder<JSObject>());
   bool must_preserve_receiver_reg =
       !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check);

   // Save necessary data before invoking an interceptor.
   // Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/ic.cc        Wed Sep  3 14:05:55 2014 UTC
+++ /branches/bleeding_edge/src/ic/ic.cc        Thu Sep  4 12:28:13 2014 UTC
@@ -215,6 +215,7 @@
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
+      case LookupIterator::UNKNOWN:
         UNREACHABLE();
       case LookupIterator::JSPROXY:
         return;
@@ -234,9 +235,9 @@
           break;
         }
         return;
-      case LookupIterator::PROPERTY:
-        if (it->HasProperty()) return;  // Yay!
-        break;
+      case LookupIterator::ACCESSOR:
+      case LookupIterator::DATA:
+        return;
     }
   }
 }
@@ -285,7 +286,7 @@
     Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
     LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
     if (it.state() == LookupIterator::ACCESS_CHECK) return false;
-    if (!it.IsFound() || !it.HasProperty()) return false;
+    if (!it.IsFound()) return false;
     Handle<PropertyCell> cell = it.GetPropertyCell();
     return cell->type()->IsConstant();
   }
@@ -976,8 +977,7 @@
   }

   // -------------- Accessors --------------
-  DCHECK(lookup->state() == LookupIterator::PROPERTY);
-  if (lookup->property_kind() == LookupIterator::ACCESSOR) {
+  if (lookup->state() == LookupIterator::ACCESSOR) {
     // Use simple field loads for some well-known callback properties.
     if (receiver_is_holder) {
       DCHECK(receiver->IsJSObject());
@@ -1032,7 +1032,7 @@
   }

   // -------------- Dictionary properties --------------
-  DCHECK(lookup->property_kind() == LookupIterator::DATA);
+  DCHECK(lookup->state() == LookupIterator::DATA);
   if (lookup->property_encoding() == LookupIterator::DICTIONARY) {
     if (kind() != Code::LOAD_IC) return slow_stub();
     if (holder->IsGlobalObject()) {
@@ -1223,6 +1223,7 @@
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
+      case LookupIterator::UNKNOWN:
         UNREACHABLE();
       case LookupIterator::JSPROXY:
         return false;
@@ -1240,11 +1241,12 @@
       case LookupIterator::ACCESS_CHECK:
         if (it->GetHolder<JSObject>()->IsAccessCheckNeeded()) return false;
         break;
-      case LookupIterator::PROPERTY:
-        if (!it->HasProperty()) break;
+      case LookupIterator::ACCESSOR:
+        return !it->IsReadOnly();
+      case LookupIterator::DATA: {
         if (it->IsReadOnly()) return false;
-        if (it->property_kind() == LookupIterator::ACCESSOR) return true;
-        if (it->GetHolder<Object>().is_identical_to(receiver)) {
+        Handle<JSObject> holder = it->GetHolder<JSObject>();
+        if (receiver.is_identical_to(holder)) {
           it->PrepareForDataProperty(value);
           // The previous receiver map might just have been deprecated,
           // so reload it.
@@ -1253,14 +1255,15 @@
         }

         // Receiver != holder.
+        PrototypeIterator iter(it->isolate(), receiver);
         if (receiver->IsJSGlobalProxy()) {
-          PrototypeIterator iter(it->isolate(), receiver);
           return it->GetHolder<Object>().is_identical_to(
               PrototypeIterator::GetCurrent(iter));
         }

         it->PrepareTransitionToDataProperty(value, NONE, store_mode);
         return it->IsCacheableTransition();
+      }
     }
   }

@@ -1417,8 +1420,7 @@
   }

   // -------------- Accessors --------------
-  DCHECK(lookup->state() == LookupIterator::PROPERTY);
-  if (lookup->property_kind() == LookupIterator::ACCESSOR) {
+  if (lookup->state() == LookupIterator::ACCESSOR) {
     if (!holder->HasFastProperties()) return slow_stub();
     Handle<Object> accessors = lookup->GetAccessors();
     if (accessors->IsExecutableAccessorInfo()) {
@@ -1452,7 +1454,7 @@
   }

   // -------------- Dictionary properties --------------
-  DCHECK(lookup->property_kind() == LookupIterator::DATA);
+  DCHECK(lookup->state() == LookupIterator::DATA);
   if (lookup->property_encoding() == LookupIterator::DICTIONARY) {
     if (holder->IsGlobalObject()) {
       Handle<PropertyCell> cell = lookup->GetPropertyCell();
=======================================
--- /branches/bleeding_edge/src/ic/mips/handler-compiler-mips.cc Thu Sep 4 08:59:42 2014 UTC +++ /branches/bleeding_edge/src/ic/mips/handler-compiler-mips.cc Thu Sep 4 12:28:13 2014 UTC
@@ -710,8 +710,7 @@
       !holder().is_identical_to(it->GetHolder<JSObject>());
   bool must_preserve_receiver_reg =
       !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check);

   // Save necessary data before invoking an interceptor.
   // Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/mips64/handler-compiler-mips64.cc Thu Sep 4 08:59:42 2014 UTC +++ /branches/bleeding_edge/src/ic/mips64/handler-compiler-mips64.cc Thu Sep 4 12:28:13 2014 UTC
@@ -710,8 +710,7 @@
       !holder().is_identical_to(it->GetHolder<JSObject>());
   bool must_preserve_receiver_reg =
       !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check);

   // Save necessary data before invoking an interceptor.
   // Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/x64/handler-compiler-x64.cc Wed Sep 3 13:14:55 2014 UTC +++ /branches/bleeding_edge/src/ic/x64/handler-compiler-x64.cc Thu Sep 4 12:28:13 2014 UTC
@@ -694,8 +694,7 @@
       !holder().is_identical_to(it->GetHolder<JSObject>());
   bool must_preserve_receiver_reg =
       !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check);

   // Save necessary data before invoking an interceptor.
   // Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/ic/x87/handler-compiler-x87.cc Wed Aug 27 04:49:41 2014 UTC +++ /branches/bleeding_edge/src/ic/x87/handler-compiler-x87.cc Thu Sep 4 12:28:13 2014 UTC
@@ -747,8 +747,7 @@
       !holder().is_identical_to(it->GetHolder<JSObject>());
   bool must_preserve_receiver_reg =
       !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
+ (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check);

   // Save necessary data before invoking an interceptor.
   // Requires a frame to make GC aware of pushed pointers.
=======================================
--- /branches/bleeding_edge/src/lookup-inl.h    Wed Sep  3 14:05:55 2014 UTC
+++ /branches/bleeding_edge/src/lookup-inl.h    Thu Sep  4 12:28:13 2014 UTC
@@ -31,7 +31,8 @@
 }


-LookupIterator::State LookupIterator::LookupInHolder(Map* map) {
+LookupIterator::State LookupIterator::LookupInHolder(Map* map,
+                                                     JSReceiver* holder) {
   STATIC_ASSERT(INTERCEPTOR == BEFORE_PROPERTY);
   DisallowHeapAllocation no_gc;
   switch (state_) {
@@ -47,14 +48,35 @@
     case INTERCEPTOR:
       if (map->is_dictionary_map()) {
         property_encoding_ = DICTIONARY;
+        if (holder == NULL) return UNKNOWN;
+ NameDictionary* dict = JSObject::cast(holder)->property_dictionary();
+        number_ = dict->FindEntry(name_);
+        if (number_ == NameDictionary::kNotFound) return NOT_FOUND;
+        property_details_ = dict->DetailsAt(number_);
+        if (holder->IsGlobalObject()) {
+          if (property_details_.IsDeleted()) return NOT_FOUND;
+          PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_));
+          if (cell->value()->IsTheHole()) return NOT_FOUND;
+        }
       } else {
         DescriptorArray* descriptors = map->instance_descriptors();
         number_ = descriptors->SearchWithCache(*name_, map);
         if (number_ == DescriptorArray::kNotFound) return NOT_FOUND;
         property_encoding_ = DESCRIPTOR;
+        property_details_ = descriptors->GetDetails(number_);
       }
-      return PROPERTY;
-    case PROPERTY:
+      has_property_ = true;
+      switch (property_details_.type()) {
+        case v8::internal::CONSTANT:
+        case v8::internal::FIELD:
+        case v8::internal::NORMAL:
+          return DATA;
+        case v8::internal::CALLBACKS:
+          return ACCESSOR;
+      }
+    case ACCESSOR:
+    case DATA:
+    case UNKNOWN:
       return NOT_FOUND;
     case JSPROXY:
     case TRANSITION:
=======================================
--- /branches/bleeding_edge/src/lookup.cc       Tue Aug 26 16:32:51 2014 UTC
+++ /branches/bleeding_edge/src/lookup.cc       Thu Sep  4 12:28:13 2014 UTC
@@ -14,25 +14,28 @@


 void LookupIterator::Next() {
+  DCHECK_NE(JSPROXY, state_);
+  DCHECK_NE(TRANSITION, state_);
   DisallowHeapAllocation no_gc;
   has_property_ = false;

-  JSReceiver* holder = NULL;
+  JSReceiver* holder =
+      maybe_holder_.is_null() ? NULL : *maybe_holder_.ToHandleChecked();
   Map* map = *holder_map_;

   // Perform lookup on current holder.
-  state_ = LookupInHolder(map);
+  state_ = LookupInHolder(map, holder);
+  if (IsFound()) return;

   // Continue lookup if lookup on current holder failed.
-  while (!IsFound()) {
+  do {
     JSReceiver* maybe_holder = NextHolder(map);
     if (maybe_holder == NULL) break;
     holder = maybe_holder;
     map = holder->map();
-    state_ = LookupInHolder(map);
-  }
+    state_ = LookupInHolder(map, holder);
+  } while (!IsFound());

-  // Either was found in the receiver, or the receiver has no prototype.
   if (holder == NULL) return;

   maybe_holder_ = handle(holder, isolate_);
@@ -79,60 +82,17 @@
   DCHECK(is_guaranteed_to_have_holder());
return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type);
 }
-
-
-bool LookupIterator::HasProperty() {
-  DCHECK_EQ(PROPERTY, state_);
-  DCHECK(is_guaranteed_to_have_holder());
-
-  if (property_encoding_ == DICTIONARY) {
-    Handle<JSObject> holder = GetHolder<JSObject>();
-    number_ = holder->property_dictionary()->FindEntry(name_);
-    if (number_ == NameDictionary::kNotFound) return false;
-
-    property_details_ = holder->property_dictionary()->DetailsAt(number_);
-    // Holes in dictionary cells are absent values.
-    if (holder->IsGlobalObject() &&
-        (property_details_.IsDeleted() || FetchValue()->IsTheHole())) {
-      return false;
-    }
-  } else {
- // Can't use descriptor_number() yet because has_property_ is still false.
-    property_details_ =
-        holder_map_->instance_descriptors()->GetDetails(number_);
-  }
-
-  LoadPropertyKind();
-
-  has_property_ = true;
-  return true;
-}
-
-
-void LookupIterator::LoadPropertyKind() {
-  switch (property_details_.type()) {
-    case v8::internal::FIELD:
-    case v8::internal::NORMAL:
-    case v8::internal::CONSTANT:
-      property_kind_ = DATA;
-      break;
-    case v8::internal::CALLBACKS:
-      property_kind_ = ACCESSOR;
-      break;
-  }
-}


 void LookupIterator::ReloadPropertyInformation() {
   state_ = BEFORE_PROPERTY;
-  state_ = LookupInHolder(*holder_map_);
-  DCHECK(IsFound());
-  HasProperty();
+  state_ = LookupInHolder(*holder_map_, *maybe_holder_.ToHandleChecked());
+  DCHECK(IsFound() || holder_map_->is_dictionary_map());
 }


 void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
-  DCHECK(has_property_);
+  DCHECK(state_ == DATA || state_ == ACCESSOR);
   DCHECK(HolderIsReceiverOrHiddenPrototype());
   if (property_encoding_ == DICTIONARY) return;
   holder_map_ =
@@ -144,7 +104,7 @@

 void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
PropertyAttributes attributes) {
-  DCHECK(has_property_);
+  DCHECK(state_ == DATA || state_ == ACCESSOR);
   DCHECK(HolderIsReceiverOrHiddenPrototype());
   Handle<JSObject> holder = GetHolder<JSObject>();
   if (property_encoding_ != DICTIONARY) {
@@ -166,9 +126,9 @@
     Handle<Object> value, PropertyAttributes attributes,
     Object::StoreFromKeyed store_mode) {
   if (state_ == TRANSITION) return;
-  DCHECK(!has_property_ || property_kind_ != ACCESSOR);
-  DCHECK(!(has_property_ || state_ == JSPROXY) ||
-         !HolderIsReceiverOrHiddenPrototype());
+  DCHECK(state_ != LookupIterator::ACCESSOR ||
+         GetAccessors()->IsDeclaredAccessorInfo());
+  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
@@ -224,8 +184,7 @@
   // Install the accessor into the dictionary-mode object.
   PropertyDetails details(attributes, CALLBACKS, 0);
   Handle<AccessorPair> pair;
-  if (IsFound() && HasProperty() && property_kind() == ACCESSOR &&
-      GetAccessors()->IsAccessorPair()) {
+  if (state() == 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) {
@@ -331,15 +290,13 @@


 Handle<Object> LookupIterator::GetAccessors() const {
-  DCHECK(has_property_);
-  DCHECK_EQ(ACCESSOR, property_kind_);
+  DCHECK_EQ(ACCESSOR, state_);
   return FetchValue();
 }


 Handle<Object> LookupIterator::GetDataValue() const {
-  DCHECK(has_property_);
-  DCHECK_EQ(DATA, property_kind_);
+  DCHECK_EQ(DATA, state_);
   Handle<Object> value = FetchValue();
   return value;
 }
@@ -347,7 +304,7 @@

 void LookupIterator::WriteDataValue(Handle<Object> value) {
   DCHECK(is_guaranteed_to_have_holder());
-  DCHECK(has_property_);
+  DCHECK_EQ(DATA, state_);
   Handle<JSObject> holder = GetHolder<JSObject>();
   if (property_encoding_ == DICTIONARY) {
     NameDictionary* property_dictionary = holder->property_dictionary();
=======================================
--- /branches/bleeding_edge/src/lookup.h        Wed Sep  3 14:05:55 2014 UTC
+++ /branches/bleeding_edge/src/lookup.h        Thu Sep  4 12:28:13 2014 UTC
@@ -34,18 +34,15 @@
     INTERCEPTOR,
     JSPROXY,
     NOT_FOUND,
-    PROPERTY,
+    UNKNOWN,  // Dictionary-mode holder map without a holder.
+    ACCESSOR,
+    DATA,
     TRANSITION,
// Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a
     // PROPERTY lookup.
     BEFORE_PROPERTY = INTERCEPTOR
   };

-  enum PropertyKind {
-    DATA,
-    ACCESSOR
-  };
-
   enum PropertyEncoding {
     DICTIONARY,
     DESCRIPTOR
@@ -55,7 +52,6 @@
                  Configuration configuration = PROTOTYPE_CHAIN)
       : configuration_(ComputeConfiguration(configuration, name)),
         state_(NOT_FOUND),
-        property_kind_(DATA),
         property_encoding_(DESCRIPTOR),
         property_details_(NONE, NORMAL, Representation::None()),
         isolate_(name->GetIsolate()),
@@ -73,7 +69,6 @@
                  Configuration configuration = PROTOTYPE_CHAIN)
       : configuration_(ComputeConfiguration(configuration, name)),
         state_(NOT_FOUND),
-        property_kind_(DATA),
         property_encoding_(DESCRIPTOR),
         property_details_(NONE, NORMAL, Representation::None()),
         isolate_(name->GetIsolate()),
@@ -118,10 +113,6 @@
   bool HasAccess(v8::AccessType access_type) const;

   /* PROPERTY */
- // HasProperty needs to be called before any of the other PROPERTY methods
-  // below can be used. It ensures that we are able to provide a definite
-  // answer, and loads extra information about the property.
-  bool HasProperty();
   void PrepareForDataProperty(Handle<Object> value);
   void PrepareTransitionToDataProperty(Handle<Object> value,
                                        PropertyAttributes attributes,
@@ -131,7 +122,6 @@
state_ == TRANSITION && transition_map()->GetBackPointer()->IsMap();
     if (cacheable) {
       property_details_ = transition_map_->GetLastDescriptorDetails();
-      LoadPropertyKind();
       has_property_ = true;
     }
     return cacheable;
@@ -142,10 +132,6 @@
   void TransitionToAccessorProperty(AccessorComponent component,
                                     Handle<Object> accessor,
                                     PropertyAttributes attributes);
-  PropertyKind property_kind() const {
-    DCHECK(has_property_);
-    return property_kind_;
-  }
   PropertyEncoding property_encoding() const {
     DCHECK(has_property_);
     return property_encoding_;
@@ -173,10 +159,9 @@
   Handle<Map> GetReceiverMap() const;

   MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map);
-  inline State LookupInHolder(Map* map);
+  inline State LookupInHolder(Map* map, JSReceiver* holder);
   Handle<Object> FetchValue() const;
   void ReloadPropertyInformation();
-  void LoadPropertyKind();

   bool IsBootstrapping() const;

@@ -219,7 +204,6 @@
   Configuration configuration_;
   State state_;
   bool has_property_;
-  PropertyKind property_kind_;
   PropertyEncoding property_encoding_;
   PropertyDetails property_details_;
   Isolate* isolate_;
=======================================
--- /branches/bleeding_edge/src/objects.cc      Thu Sep  4 11:27:20 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Thu Sep  4 12:28:13 2014 UTC
@@ -110,6 +110,7 @@
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
+      case LookupIterator::UNKNOWN:
         UNREACHABLE();
       case LookupIterator::JSPROXY:
         return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(),
@@ -124,18 +125,12 @@
       case LookupIterator::ACCESS_CHECK:
         if (it->HasAccess(v8::ACCESS_GET)) break;
         return JSObject::GetPropertyWithFailedAccessCheck(it);
-      case LookupIterator::PROPERTY:
-        if (it->HasProperty()) {
-          switch (it->property_kind()) {
-            case LookupIterator::ACCESSOR:
-              return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
-                                             it->GetHolder<JSObject>(),
-                                             it->GetAccessors());
-            case LookupIterator::DATA:
-              return it->GetDataValue();
-          }
-        }
-        break;
+      case LookupIterator::ACCESSOR:
+        return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
+                                       it->GetHolder<JSObject>(),
+                                       it->GetAccessors());
+      case LookupIterator::DATA:
+        return it->GetDataValue();
     }
   }
   return it->factory()->undefined_value();
@@ -156,6 +151,7 @@
       case LookupIterator::INTERCEPTOR:
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
+      case LookupIterator::UNKNOWN:
         UNREACHABLE();
       case LookupIterator::ACCESS_CHECK:
         if (it->HasAccess(v8::ACCESS_GET)) continue;
@@ -163,18 +159,14 @@
       case LookupIterator::JSPROXY:
         it->NotFound();
         return it->isolate()->factory()->undefined_value();
-      case LookupIterator::PROPERTY:
-        if (!it->HasProperty()) continue;
-        switch (it->property_kind()) {
-          case LookupIterator::DATA:
-            return it->GetDataValue();
-          case LookupIterator::ACCESSOR:
-            // TODO(verwaest): For now this doesn't call into
- // ExecutableAccessorInfo, since clients don't need it. Update once
-            // relevant.
-            it->NotFound();
-            return it->isolate()->factory()->undefined_value();
-        }
+      case LookupIterator::ACCESSOR:
+        // TODO(verwaest): For now this doesn't call into
+        // ExecutableAccessorInfo, since clients don't need it. Update once
+        // relevant.
+        it->NotFound();
+        return it->isolate()->factory()->undefined_value();
+      case LookupIterator::DATA:
+        return it->GetDataValue();
     }
   }
   return it->isolate()->factory()->undefined_value();
@@ -582,9 +574,7 @@

 static bool FindAllCanReadHolder(LookupIterator* it) {
   for (; it->IsFound(); it->Next()) {
-    if (it->state() == LookupIterator::PROPERTY &&
-        it->HasProperty() &&
-        it->property_kind() == LookupIterator::ACCESSOR) {
+    if (it->state() == LookupIterator::ACCESSOR) {
       Handle<Object> accessors = it->GetAccessors();
       if (accessors->IsAccessorInfo()) {
         if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
@@ -623,8 +613,7 @@

 static bool FindAllCanWriteHolder(LookupIterator* it) {
   for (; it->IsFound(); it->Next()) {
-    if (it->state() == LookupIterator::PROPERTY && it->HasProperty() &&
-        it->property_kind() == LookupIterator::ACCESSOR) {
+    if (it->state() == LookupIterator::ACCESSOR) {
       Handle<Object> accessors = it->GetAccessors();
       if (accessors->IsAccessorInfo()) {
         if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
@@ -2830,6 +2819,7 @@
   for (; it->IsFound(); it->Next()) {
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
+      case LookupIterator::UNKNOWN:
         UNREACHABLE();

       case LookupIterator::ACCESS_CHECK:
@@ -2875,24 +2865,25 @@
         }
         break;

-      case LookupIterator::PROPERTY:
-        if (!it->HasProperty()) break;
+      case LookupIterator::ACCESSOR:
         if (it->property_details().IsReadOnly()) {
           return WriteToReadOnlyProperty(it, value, strict_mode);
         }
-        switch (it->property_kind()) {
-          case LookupIterator::ACCESSOR:
-            if (it->HolderIsReceiverOrHiddenPrototype() ||
-                !it->GetAccessors()->IsDeclaredAccessorInfo()) {
-              return SetPropertyWithAccessor(it->GetReceiver(), it->name(),
- value, it->GetHolder<JSObject>(), - it->GetAccessors(), strict_mode);
-            }
-            break;
-          case LookupIterator::DATA:
-            if (it->HolderIsReceiverOrHiddenPrototype()) {
-              return SetDataProperty(it, value);
-            }
+        if (it->HolderIsReceiverOrHiddenPrototype() ||
+            !it->GetAccessors()->IsDeclaredAccessorInfo()) {
+ return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value,
+                                         it->GetHolder<JSObject>(),
+                                         it->GetAccessors(), strict_mode);
+        }
+        done = true;
+        break;
+
+      case LookupIterator::DATA:
+        if (it->property_details().IsReadOnly()) {
+          return WriteToReadOnlyProperty(it, value, strict_mode);
+        }
+        if (it->HolderIsReceiverOrHiddenPrototype()) {
+          return SetDataProperty(it, value);
         }
         done = true;
         break;
@@ -3825,6 +3816,7 @@
       case LookupIterator::JSPROXY:
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
+      case LookupIterator::UNKNOWN:
         UNREACHABLE();

       case LookupIterator::ACCESS_CHECK:
@@ -3833,87 +3825,92 @@
         }
         break;

-      case LookupIterator::PROPERTY: {
-        if (!it.HasProperty()) break;
+      case LookupIterator::ACCESSOR: {
         PropertyDetails details = it.property_details();
Handle<Object> old_value = it.isolate()->factory()->the_hole_value();
-        switch (it.property_kind()) {
-          case LookupIterator::ACCESSOR: {
- // Ensure the context isn't changed after calling into accessors.
-            AssertNoContextChange ncc(it.isolate());
+        // Ensure the context isn't changed after calling into accessors.
+        AssertNoContextChange ncc(it.isolate());

-            Handle<Object> accessors = it.GetAccessors();
+        Handle<Object> accessors = it.GetAccessors();

-            if (is_observed && accessors->IsAccessorInfo()) {
-              ASSIGN_RETURN_ON_EXCEPTION(
-                  it.isolate(), old_value,
-                  GetPropertyWithAccessor(it.GetReceiver(), it.name(),
- it.GetHolder<JSObject>(), accessors),
-                  Object);
-            }
+        if (is_observed && accessors->IsAccessorInfo()) {
+          ASSIGN_RETURN_ON_EXCEPTION(
+              it.isolate(), old_value,
+              GetPropertyWithAccessor(it.GetReceiver(), it.name(),
+                                      it.GetHolder<JSObject>(), accessors),
+              Object);
+        }

- // Special handling for ExecutableAccessorInfo, which behaves like a
-            // data property.
-            if (handling == DONT_FORCE_FIELD &&
-                accessors->IsExecutableAccessorInfo()) {
-              Handle<Object> result;
-              ASSIGN_RETURN_ON_EXCEPTION(
-                  it.isolate(), result,
-                  JSObject::SetPropertyWithAccessor(
-                      it.GetReceiver(), it.name(), value,
-                      it.GetHolder<JSObject>(), accessors, STRICT),
-                  Object);
-              DCHECK(result->SameValue(*value));
+ // Special handling for ExecutableAccessorInfo, which behaves like a
+        // data property.
+        if (handling == DONT_FORCE_FIELD &&
+            accessors->IsExecutableAccessorInfo()) {
+          Handle<Object> result;
+          ASSIGN_RETURN_ON_EXCEPTION(
+              it.isolate(), result,
+ JSObject::SetPropertyWithAccessor(it.GetReceiver(), it.name(), + value, it.GetHolder<JSObject>(),
+                                                accessors, STRICT),
+              Object);
+          DCHECK(result->SameValue(*value));

-              if (details.attributes() == attributes) {
-                // Regular property update if the attributes match.
-                if (is_observed && !old_value->SameValue(*value)) {
-                  // If we are setting the prototype of a function and are
- // observed, don't send change records because the prototype
-                  // handles that itself.
-                  if (!object->IsJSFunction() ||
-                      
!Name::Equals(it.isolate()->factory()->prototype_string(),
-                                    name) ||
-                      !Handle<JSFunction>::cast(object)
-                           ->should_have_prototype()) {
-                    EnqueueChangeRecord(object, "update", name, old_value);
-                  }
-                }
-                return value;
+          if (details.attributes() == attributes) {
+            // Regular property update if the attributes match.
+            if (is_observed && !old_value->SameValue(*value)) {
+              // If we are setting the prototype of a function and are
+              // observed, don't send change records because the prototype
+              // handles that itself.
+              if (!object->IsJSFunction() ||
+                  !Name::Equals(it.isolate()->factory()->prototype_string(),
+                                name) ||
+ !Handle<JSFunction>::cast(object)->should_have_prototype()) {
+                EnqueueChangeRecord(object, "update", name, old_value);
               }
+            }
+            return value;
+          }

-              // Reconfigure the accessor if attributes mismatch.
-              Handle<ExecutableAccessorInfo> new_data =
-                  Accessors::CloneAccessor(
-                      it.isolate(),
-                      Handle<ExecutableAccessorInfo>::cast(accessors));
-              new_data->set_property_attributes(attributes);
- // By clearing the setter we don't have to introduce a lookup to
-              // the setter, simply make it unavailable to reflect the
-              // attributes.
-              if (attributes & READ_ONLY) new_data->clear_setter();
-              SetPropertyCallback(object, name, new_data, attributes);
-              if (is_observed) {
-                if (old_value->SameValue(*value)) {
-                  old_value = it.isolate()->factory()->the_hole_value();
-                }
- EnqueueChangeRecord(object, "reconfigure", name, old_value);
-              }
-              return value;
+          // Reconfigure the accessor if attributes mismatch.
+ Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( + it.isolate(), Handle<ExecutableAccessorInfo>::cast(accessors));
+          new_data->set_property_attributes(attributes);
+          // By clearing the setter we don't have to introduce a lookup to
+          // the setter, simply make it unavailable to reflect the
+          // attributes.
+          if (attributes & READ_ONLY) new_data->clear_setter();
+          SetPropertyCallback(object, name, new_data, attributes);
+          if (is_observed) {
+            if (old_value->SameValue(*value)) {
+              old_value = it.isolate()->factory()->the_hole_value();
             }
+            EnqueueChangeRecord(object, "reconfigure", name, old_value);
+          }
+          return value;
+        }

-            // Regular accessor. Reconfigure to data property.
-            break;
+        it.ReconfigureDataProperty(value, attributes);
+        it.PrepareForDataProperty(value);
+        it.WriteDataValue(value);
+
+        if (is_observed) {
+          if (old_value->SameValue(*value)) {
+            old_value = it.isolate()->factory()->the_hole_value();
           }
+          EnqueueChangeRecord(object, "reconfigure", name, old_value);
+        }

-          case LookupIterator::DATA:
-            // Regular property update if the attributes match.
-            if (details.attributes() == attributes) {
-              return SetDataProperty(&it, value);
-            }
-            // Reconfigure the data property if the attributes mismatch.
-            if (is_observed) old_value = it.GetDataValue();
+        return value;
+      }
+
+      case LookupIterator::DATA: {
+        PropertyDetails details = it.property_details();
+ Handle<Object> old_value = it.isolate()->factory()->the_hole_value();
+        // Regular property update if the attributes match.
+        if (details.attributes() == attributes) {
+          return SetDataProperty(&it, value);
         }
+        // Reconfigure the data property if the attributes mismatch.
+        if (is_observed) old_value = it.GetDataValue();

         it.ReconfigureDataProperty(value, attributes);
         it.PrepareForDataProperty(value);
@@ -3996,6 +3993,7 @@
   for (; it->IsFound(); it->Next()) {
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
+      case LookupIterator::UNKNOWN:
       case LookupIterator::TRANSITION:
         UNREACHABLE();
       case LookupIterator::JSPROXY:
@@ -4012,11 +4010,9 @@
       case LookupIterator::ACCESS_CHECK:
         if (it->HasAccess(v8::ACCESS_HAS)) break;
         return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
-      case LookupIterator::PROPERTY:
-        if (it->HasProperty()) {
-          return maybe(it->property_details().attributes());
-        }
-        break;
+      case LookupIterator::ACCESSOR:
+      case LookupIterator::DATA:
+        return maybe(it->property_details().attributes());
     }
   }
   return maybe(ABSENT);
@@ -4693,7 +4689,7 @@
   Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string();
   LookupIterator it(object, hidden, LookupIterator::OWN_SKIP_INTERCEPTOR);
   CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
-  return it.IsFound() && it.HasProperty();
+  return it.IsFound();
 }


@@ -4726,10 +4722,10 @@
     LookupIterator it(handle(this), isolate->factory()->hidden_string(),
                       LookupIterator::OWN_SKIP_INTERCEPTOR);
     CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
-    if (it.IsFound() && it.HasProperty()) {
-      DCHECK_EQ(LookupIterator::DATA, it.property_kind());
+    if (it.state() == LookupIterator::DATA) {
       return *it.GetDataValue();
     }
+    DCHECK(!it.IsFound());
     return GetHeap()->undefined_value();
   }
 }
@@ -4926,12 +4922,14 @@

   bool is_observed = object->map()->is_observed() &&
                      *name != it.isolate()->heap()->hidden_string();
+  Handle<Object> old_value = it.isolate()->factory()->the_hole_value();

   for (; it.IsFound(); it.Next()) {
     switch (it.state()) {
       case LookupIterator::JSPROXY:
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
+      case LookupIterator::UNKNOWN:
         UNREACHABLE();
       case LookupIterator::ACCESS_CHECK:
         if (it.HasAccess(v8::ACCESS_DELETE)) break;
@@ -4949,8 +4947,12 @@
         if (it.isolate()->has_pending_exception()) return maybe_result;
         break;
       }
-      case LookupIterator::PROPERTY: {
-        if (!it.HasProperty()) continue;
+      case LookupIterator::DATA:
+        if (is_observed) {
+          old_value = it.GetDataValue();
+        }
+      // Fall through.
+      case LookupIterator::ACCESSOR: {
         if (delete_mode != FORCE_DELETION && !it.IsConfigurable()) {
           // Fail if the property is not configurable.
           if (delete_mode == STRICT_DELETION) {
@@ -4962,17 +4964,6 @@
           }
           return it.isolate()->factory()->false_value();
         }
-
-        Handle<Object> old_value;
-        if (is_observed) {
-          switch (it.property_kind()) {
-            case LookupIterator::ACCESSOR:
-              old_value = it.isolate()->factory()->the_hole_value();
-              break;
-            case LookupIterator::DATA:
-              old_value = it.GetDataValue();
-          }
-        }

         PropertyNormalizationMode mode = object->map()->is_prototype_map()
                                              ? KEEP_INOBJECT_PROPERTIES
@@ -6150,7 +6141,7 @@
LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
       CHECK(GetPropertyAttributes(&it).has_value);
       preexists = it.IsFound();
-      if (preexists && (it.property_kind() == LookupIterator::DATA ||
+      if (preexists && (it.state() == LookupIterator::DATA ||
                         it.GetAccessors()->IsAccessorInfo())) {
         old_value = GetProperty(&it).ToHandleChecked();
       }
@@ -6314,6 +6305,7 @@
         case LookupIterator::INTERCEPTOR:
         case LookupIterator::NOT_FOUND:
         case LookupIterator::TRANSITION:
+        case LookupIterator::UNKNOWN:
           UNREACHABLE();

         case LookupIterator::ACCESS_CHECK:
@@ -6326,20 +6318,16 @@
         case LookupIterator::JSPROXY:
           return isolate->factory()->undefined_value();

-        case LookupIterator::PROPERTY:
-          if (!it.HasProperty()) continue;
-          switch (it.property_kind()) {
-            case LookupIterator::DATA:
-              continue;
-            case LookupIterator::ACCESSOR: {
-              Handle<Object> maybe_pair = it.GetAccessors();
-              if (maybe_pair->IsAccessorPair()) {
-                return handle(
- AccessorPair::cast(*maybe_pair)->GetComponent(component),
-                    isolate);
-              }
-            }
+        case LookupIterator::DATA:
+          continue;
+        case LookupIterator::ACCESSOR: {
+          Handle<Object> maybe_pair = it.GetAccessors();
+          if (maybe_pair->IsAccessorPair()) {
+            return handle(
+                AccessorPair::cast(*maybe_pair)->GetComponent(component),
+                isolate);
           }
+        }
       }
     }
   }
@@ -12849,7 +12837,7 @@
                       LookupIterator::OWN_SKIP_INTERCEPTOR);
     CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
     CHECK(it.IsFound());
-    CHECK(it.HasProperty());
+    CHECK_EQ(LookupIterator::ACCESSOR, it.state());
     return it.IsReadOnly();
   }
   return false;
@@ -13275,7 +13263,7 @@
   LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
   Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
   if (!maybe_result.has_value) return Maybe<bool>();
- return maybe(it.IsFound() && it.property_kind() == LookupIterator::ACCESSOR);
+  return maybe(it.state() == LookupIterator::ACCESSOR);
 }


=======================================
--- /branches/bleeding_edge/src/runtime.cc      Thu Sep  4 11:27:20 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Thu Sep  4 12:28:13 2014 UTC
@@ -1990,8 +1990,7 @@
     if (attrs == ABSENT) return factory->undefined_value();

     // Get AccessorPair if present.
-    if (it.state() == LookupIterator::PROPERTY &&
-        it.property_kind() == LookupIterator::ACCESSOR &&
+    if (it.state() == LookupIterator::ACCESSOR &&
         it.GetAccessors()->IsAccessorPair()) {
       maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors());
     }
@@ -2323,7 +2322,7 @@
     // Ignore if we can't reconfigure the value.
     if ((old_attributes & DONT_DELETE) != 0) {
       if ((old_attributes & READ_ONLY) != 0 ||
-          it.property_kind() == LookupIterator::ACCESSOR) {
+          it.state() == LookupIterator::ACCESSOR) {
         return *value;
       }
       attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
@@ -2468,7 +2467,7 @@
     // Ignore if we can't reconfigure the value.
     if ((old_attributes & DONT_DELETE) != 0) {
       if ((old_attributes & READ_ONLY) != 0 ||
-          it.property_kind() == LookupIterator::ACCESSOR) {
+          it.state() == LookupIterator::ACCESSOR) {
         return *value;
       }
       attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
@@ -4891,8 +4890,8 @@
         // Lookup cache miss.  Perform lookup and update the cache if
         // appropriate.
         LookupIterator it(receiver, key, LookupIterator::OWN);
-        if (it.IsFound() && it.state() == LookupIterator::PROPERTY &&
-            it.HasProperty() && it.property_details().type() == FIELD) {
+        if (it.state() == LookupIterator::DATA &&
+            it.property_details().type() == FIELD) {
           FieldIndex field_index = it.GetFieldIndex();
           // Do not track double fields in the keyed lookup cache. Reading
           // double values requires boxing.
@@ -5050,8 +5049,7 @@

   // Take special care when attributes are different and there is already
   // a property.
-  if (it.IsFound() && it.HasProperty() &&
-      it.property_kind() == LookupIterator::ACCESSOR) {
+  if (it.state() == LookupIterator::ACCESSOR) {
     // Use IgnoreAttributes version since a readonly property may be
     // overridden and SetProperty does not allow this.
     Handle<Object> result;
@@ -10898,6 +10896,7 @@
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
+      case LookupIterator::UNKNOWN:
         UNREACHABLE();
       case LookupIterator::ACCESS_CHECK:
         // Ignore access checks.
@@ -10905,30 +10904,25 @@
       case LookupIterator::INTERCEPTOR:
       case LookupIterator::JSPROXY:
         return it->isolate()->factory()->undefined_value();
-      case LookupIterator::PROPERTY:
-        if (!it->HasProperty()) continue;
-        switch (it->property_kind()) {
-          case LookupIterator::ACCESSOR: {
-            Handle<Object> accessors = it->GetAccessors();
-            if (!accessors->IsAccessorInfo()) {
-              return it->isolate()->factory()->undefined_value();
-            }
-            MaybeHandle<Object> maybe_result =
- JSObject::GetPropertyWithAccessor(it->GetReceiver(), it->name(), - it->GetHolder<JSObject>(),
-                                                  accessors);
-            Handle<Object> result;
-            if (!maybe_result.ToHandle(&result)) {
-              result =
- handle(it->isolate()->pending_exception(), it->isolate());
-              it->isolate()->clear_pending_exception();
-              if (has_caught != NULL) *has_caught = true;
-            }
-            return result;
-          }
-          case LookupIterator::DATA:
-            return it->GetDataValue();
+      case LookupIterator::ACCESSOR: {
+        Handle<Object> accessors = it->GetAccessors();
+        if (!accessors->IsAccessorInfo()) {
+          return it->isolate()->factory()->undefined_value();
+        }
+ MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithAccessor(
+            it->GetReceiver(), it->name(), it->GetHolder<JSObject>(),
+            accessors);
+        Handle<Object> result;
+        if (!maybe_result.ToHandle(&result)) {
+ result = handle(it->isolate()->pending_exception(), it->isolate());
+          it->isolate()->clear_pending_exception();
+          if (has_caught != NULL) *has_caught = true;
         }
+        return result;
+      }
+
+      case LookupIterator::DATA:
+        return it->GetDataValue();
     }
   }

@@ -10983,8 +10977,7 @@
   if (!it.IsFound()) return isolate->heap()->undefined_value();

   Handle<Object> maybe_pair;
-  if (it.state() == LookupIterator::PROPERTY &&
-      it.property_kind() == LookupIterator::ACCESSOR) {
+  if (it.state() == LookupIterator::ACCESSOR) {
     maybe_pair = it.GetAccessors();
   }

=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Wed Sep 3 14:05:55 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-api.cc Thu Sep 4 12:28:13 2014 UTC
@@ -2045,8 +2045,7 @@
   i::LookupResult lookup(i_isolate);
   i::Handle<i::String> name(v8::Utils::OpenHandle(*v8_str("length")));
   i::LookupIterator it(a, name, i::LookupIterator::OWN_SKIP_INTERCEPTOR);
-  CHECK_NE(i::LookupIterator::ACCESS_CHECK, it.state());
-  CHECK(it.HasProperty());
+  CHECK_EQ(i::LookupIterator::ACCESSOR, it.state());
   CHECK(it.GetAccessors()->IsExecutableAccessorInfo());
 }

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to