Simplify the LookupIterator
authorverwaest@chromium.org <verwaest@chromium.org>
Tue, 16 Sep 2014 12:42:04 +0000 (12:42 +0000)
committerverwaest@chromium.org <verwaest@chromium.org>
Tue, 16 Sep 2014 12:42:04 +0000 (12:42 +0000)
BUG=
R=ishell@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23975 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen.cc
src/ic/handler-compiler.cc
src/ic/ic.cc
src/lookup-inl.h
src/lookup.cc
src/lookup.h
src/objects.cc
src/runtime.cc

index 8dbe464..4af1d2b 100644 (file)
@@ -5307,7 +5307,6 @@ HOptimizedGraphBuilder::LookupGlobalProperty(Variable* var, LookupIterator* it,
       return kUseCell;
     case LookupIterator::JSPROXY:
     case LookupIterator::TRANSITION:
-    case LookupIterator::UNKNOWN:
       UNREACHABLE();
   }
   UNREACHABLE();
index 21a653e..dd5a067 100644 (file)
@@ -228,7 +228,6 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
   bool inline_followup = false;
   switch (it->state()) {
     case LookupIterator::TRANSITION:
-    case LookupIterator::UNKNOWN:
       UNREACHABLE();
     case LookupIterator::ACCESS_CHECK:
     case LookupIterator::INTERCEPTOR:
@@ -276,7 +275,6 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
     case LookupIterator::JSPROXY:
     case LookupIterator::NOT_FOUND:
     case LookupIterator::TRANSITION:
-    case LookupIterator::UNKNOWN:
       UNREACHABLE();
     case LookupIterator::DATA: {
       DCHECK_EQ(FIELD, it->property_details().type());
index 69954a8..374b5aa 100644 (file)
@@ -215,7 +215,6 @@ static void LookupForRead(LookupIterator* it) {
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
-      case LookupIterator::UNKNOWN:
         UNREACHABLE();
       case LookupIterator::JSPROXY:
         return;
@@ -1082,7 +1081,6 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
     case LookupIterator::JSPROXY:
     case LookupIterator::NOT_FOUND:
     case LookupIterator::TRANSITION:
-    case LookupIterator::UNKNOWN:
       UNREACHABLE();
   }
 
@@ -1232,7 +1230,6 @@ bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value,
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
-      case LookupIterator::UNKNOWN:
         UNREACHABLE();
       case LookupIterator::JSPROXY:
         return false;
@@ -1503,7 +1500,6 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
     case LookupIterator::ACCESS_CHECK:
     case LookupIterator::JSPROXY:
     case LookupIterator::NOT_FOUND:
-    case LookupIterator::UNKNOWN:
       UNREACHABLE();
   }
   return slow_stub();
index cc73788..d4777a0 100644 (file)
@@ -47,7 +47,6 @@ LookupIterator::State LookupIterator::LookupInHolder(Map* map,
     // Fall through.
     case INTERCEPTOR:
       if (map->is_dictionary_map()) {
-        if (holder == NULL) return UNKNOWN;
         NameDictionary* dict = JSObject::cast(holder)->property_dictionary();
         number_ = dict->FindEntry(name_);
         if (number_ == NameDictionary::kNotFound) return NOT_FOUND;
@@ -74,7 +73,6 @@ LookupIterator::State LookupIterator::LookupInHolder(Map* map,
       }
     case ACCESSOR:
     case DATA:
-    case UNKNOWN:
       return NOT_FOUND;
     case JSPROXY:
     case TRANSITION:
index 752cd70..b855abe 100644 (file)
@@ -19,8 +19,7 @@ void LookupIterator::Next() {
   DisallowHeapAllocation no_gc;
   has_property_ = false;
 
-  JSReceiver* holder =
-      maybe_holder_.is_null() ? NULL : *maybe_holder_.ToHandleChecked();
+  JSReceiver* holder = *holder_;
   Map* map = *holder_map_;
 
   // Perform lookup on current holder.
@@ -36,39 +35,35 @@ void LookupIterator::Next() {
     state_ = LookupInHolder(map, holder);
   } while (!IsFound());
 
-  if (holder == NULL) return;
-
-  maybe_holder_ = handle(holder, isolate_);
-  holder_map_ = handle(map, isolate_);
+  if (holder != *holder_) {
+    holder_ = handle(holder, isolate_);
+    holder_map_ = handle(map, isolate_);
+  }
 }
 
 
 Handle<JSReceiver> LookupIterator::GetRoot() const {
-  Handle<Object> receiver = GetReceiver();
-  if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
+  if (receiver_->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver_);
   Handle<Object> root =
-      handle(receiver->GetRootMap(isolate_)->prototype(), isolate_);
+      handle(receiver_->GetRootMap(isolate_)->prototype(), isolate_);
   CHECK(!root->IsNull());
   return Handle<JSReceiver>::cast(root);
 }
 
 
 Handle<Map> LookupIterator::GetReceiverMap() const {
-  Handle<Object> receiver = GetReceiver();
-  if (receiver->IsNumber()) return isolate_->factory()->heap_number_map();
-  return handle(Handle<HeapObject>::cast(receiver)->map(), isolate_);
+  if (receiver_->IsNumber()) return isolate_->factory()->heap_number_map();
+  return handle(Handle<HeapObject>::cast(receiver_)->map(), isolate_);
 }
 
 
 Handle<JSObject> LookupIterator::GetStoreTarget() const {
-  Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver());
-
-  if (receiver->IsJSGlobalProxy()) {
-    PrototypeIterator iter(isolate(), receiver);
-    if (iter.IsAtEnd()) return receiver;
+  if (receiver_->IsJSGlobalProxy()) {
+    PrototypeIterator iter(isolate(), receiver_);
+    if (iter.IsAtEnd()) return Handle<JSGlobalProxy>::cast(receiver_);
     return Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
   }
-  return receiver;
+  return Handle<JSObject>::cast(receiver_);
 }
 
 
@@ -79,14 +74,13 @@ bool LookupIterator::IsBootstrapping() const {
 
 bool LookupIterator::HasAccess(v8::AccessType access_type) const {
   DCHECK_EQ(ACCESS_CHECK, state_);
-  DCHECK(is_guaranteed_to_have_holder());
   return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type);
 }
 
 
 void LookupIterator::ReloadPropertyInformation() {
   state_ = BEFORE_PROPERTY;
-  state_ = LookupInHolder(*holder_map_, *maybe_holder_.ToHandleChecked());
+  state_ = LookupInHolder(*holder_map_, *holder_);
   DCHECK(IsFound() || holder_map_->is_dictionary_map());
 }
 
@@ -148,7 +142,7 @@ void LookupIterator::ApplyTransitionToDataProperty() {
   DCHECK_EQ(TRANSITION, state_);
 
   Handle<JSObject> receiver = GetStoreTarget();
-  maybe_holder_ = receiver;
+  holder_ = receiver;
   holder_map_ = transition_map_;
   JSObject::MigrateToMap(receiver, holder_map_);
   ReloadPropertyInformation();
@@ -163,7 +157,7 @@ void LookupIterator::TransitionToAccessorProperty(
   // handled via a trap. Adding properties to primitive values is not
   // observable.
   Handle<JSObject> receiver = GetStoreTarget();
-  maybe_holder_ = receiver;
+  holder_ = receiver;
   holder_map_ =
       Map::TransitionToAccessorProperty(handle(receiver->map(), isolate_),
                                         name_, component, accessor, attributes);
@@ -208,10 +202,9 @@ bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
   // Optimization that only works if configuration_ is not mutable.
   if (!check_prototype_chain()) return true;
   DisallowHeapAllocation no_gc;
-  Handle<Object> receiver = GetReceiver();
-  if (!receiver->IsJSReceiver()) return false;
-  Object* current = *receiver;
-  JSReceiver* holder = *maybe_holder_.ToHandleChecked();
+  if (!receiver_->IsJSReceiver()) return false;
+  Object* current = *receiver_;
+  JSReceiver* holder = *holder_;
   // JSProxy do not occur as hidden prototypes.
   if (current->IsJSProxy()) {
     return JSReceiver::cast(current) == holder;
@@ -297,7 +290,6 @@ Handle<Object> LookupIterator::GetDataValue() const {
 
 
 void LookupIterator::WriteDataValue(Handle<Object> value) {
-  DCHECK(is_guaranteed_to_have_holder());
   DCHECK_EQ(DATA, state_);
   Handle<JSObject> holder = GetHolder<JSObject>();
   if (holder_map_->is_dictionary_map()) {
index ac5c27d..14ca010 100644 (file)
@@ -34,7 +34,6 @@ class LookupIterator FINAL BASE_EMBEDDED {
     INTERCEPTOR,
     JSPROXY,
     NOT_FOUND,
-    UNKNOWN,  // Dictionary-mode holder map without a holder.
     ACCESSOR,
     DATA,
     TRANSITION,
@@ -50,11 +49,10 @@ class LookupIterator FINAL BASE_EMBEDDED {
         property_details_(NONE, NORMAL, Representation::None()),
         isolate_(name->GetIsolate()),
         name_(name),
-        maybe_receiver_(receiver),
+        receiver_(receiver),
         number_(DescriptorArray::kNotFound) {
-    Handle<JSReceiver> root = GetRoot();
-    holder_map_ = handle(root->map(), isolate_);
-    maybe_holder_ = root;
+    holder_ = GetRoot();
+    holder_map_ = handle(holder_->map(), isolate_);
     Next();
   }
 
@@ -67,8 +65,8 @@ class LookupIterator FINAL BASE_EMBEDDED {
         isolate_(name->GetIsolate()),
         name_(name),
         holder_map_(holder->map(), isolate_),
-        maybe_receiver_(receiver),
-        maybe_holder_(holder),
+        receiver_(receiver),
+        holder_(holder),
         number_(DescriptorArray::kNotFound) {
     Next();
   }
@@ -85,9 +83,7 @@ class LookupIterator FINAL BASE_EMBEDDED {
   }
 
   Factory* factory() const { return isolate_->factory(); }
-  Handle<Object> GetReceiver() const {
-    return maybe_receiver_.ToHandleChecked();
-  }
+  Handle<Object> GetReceiver() const { return receiver_; }
   Handle<JSObject> GetStoreTarget() const;
   bool is_dictionary_holder() const { return holder_map_->is_dictionary_map(); }
   Handle<Map> transition_map() const {
@@ -97,7 +93,7 @@ class LookupIterator FINAL BASE_EMBEDDED {
   template <class T>
   Handle<T> GetHolder() const {
     DCHECK(IsFound());
-    return Handle<T>::cast(maybe_holder_.ToHandleChecked());
+    return Handle<T>::cast(holder_);
   }
   Handle<JSReceiver> GetRoot() const;
   bool HolderIsReceiverOrHiddenPrototype() const;
@@ -154,13 +150,6 @@ class LookupIterator FINAL BASE_EMBEDDED {
 
   bool IsBootstrapping() const;
 
-  // Methods that fetch data from the holder ensure they always have a holder.
-  // This means the receiver needs to be present as opposed to just the receiver
-  // map. Other objects in the prototype chain are transitively guaranteed to be
-  // present via the receiver map.
-  bool is_guaranteed_to_have_holder() const {
-    return !maybe_receiver_.is_null();
-  }
   bool check_hidden() const { return (configuration_ & kHidden) != 0; }
   bool check_interceptor() const {
     return !IsBootstrapping() && (configuration_ & kInterceptor) != 0;
@@ -198,8 +187,8 @@ class LookupIterator FINAL BASE_EMBEDDED {
   Handle<Name> name_;
   Handle<Map> holder_map_;
   Handle<Map> transition_map_;
-  MaybeHandle<Object> maybe_receiver_;
-  MaybeHandle<JSReceiver> maybe_holder_;
+  Handle<Object> receiver_;
+  Handle<JSReceiver> holder_;
 
   int number_;
 };
index 13688c7..783999f 100644 (file)
@@ -110,7 +110,6 @@ MaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
-      case LookupIterator::UNKNOWN:
         UNREACHABLE();
       case LookupIterator::JSPROXY:
         return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(),
@@ -151,7 +150,6 @@ Handle<Object> JSObject::GetDataProperty(LookupIterator* it) {
       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;
@@ -2806,7 +2804,6 @@ MaybeHandle<Object> Object::SetProperty(LookupIterator* it,
   for (; it->IsFound(); it->Next()) {
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
-      case LookupIterator::UNKNOWN:
         UNREACHABLE();
 
       case LookupIterator::ACCESS_CHECK:
@@ -3801,7 +3798,6 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
       case LookupIterator::JSPROXY:
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
-      case LookupIterator::UNKNOWN:
         UNREACHABLE();
 
       case LookupIterator::ACCESS_CHECK:
@@ -3978,7 +3974,6 @@ Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
   for (; it->IsFound(); it->Next()) {
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
-      case LookupIterator::UNKNOWN:
       case LookupIterator::TRANSITION:
         UNREACHABLE();
       case LookupIterator::JSPROXY:
@@ -4918,7 +4913,6 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
       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;
@@ -6297,7 +6291,6 @@ MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object,
         case LookupIterator::INTERCEPTOR:
         case LookupIterator::NOT_FOUND:
         case LookupIterator::TRANSITION:
-        case LookupIterator::UNKNOWN:
           UNREACHABLE();
 
         case LookupIterator::ACCESS_CHECK:
index 67f749b..6a11e91 100644 (file)
@@ -10927,7 +10927,6 @@ static Handle<Object> DebugGetProperty(LookupIterator* it,
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
-      case LookupIterator::UNKNOWN:
         UNREACHABLE();
       case LookupIterator::ACCESS_CHECK:
         // Ignore access checks.