Get rid of GetLazyValue and clients.
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 20 Aug 2014 10:37:23 +0000 (10:37 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 20 Aug 2014 10:37:23 +0000 (10:37 +0000)
This breaks fetching name of the constructor property of "Object"-labeled values in the heap-snapshot-generator until that's handlified and can be moved over to the LookupIterator.
BUG=
R=jkummerow@chromium.org

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

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

src/heap-snapshot-generator.cc
src/hydrogen.cc
src/ic.cc
src/objects.cc
src/objects.h
src/property.cc
src/property.h
test/cctest/test-api.cc
test/cctest/test-heap-profiler.cc

index eff9f9a..4646f4b 100644 (file)
@@ -1786,25 +1786,8 @@ String* V8HeapExplorer::GetConstructorName(JSObject* object) {
   if (object->IsJSFunction()) return heap->closure_string();
   String* constructor_name = object->constructor_name();
   if (constructor_name == heap->Object_string()) {
-    // Look up an immediate "constructor" property, if it is a function,
-    // return its name. This is for instances of binding objects, which
-    // have prototype constructor type "Object".
-    Object* constructor_prop = NULL;
-    Isolate* isolate = heap->isolate();
-    LookupResult result(isolate);
-    object->LookupOwnRealNamedProperty(
-        isolate->factory()->constructor_string(), &result);
-    if (!result.IsFound()) return object->constructor_name();
-
-    constructor_prop = result.GetLazyValue();
-    if (constructor_prop->IsJSFunction()) {
-      Object* maybe_name =
-          JSFunction::cast(constructor_prop)->shared()->name();
-      if (maybe_name->IsString()) {
-        String* name = String::cast(maybe_name);
-        if (name->length() > 0) return name;
-      }
-    }
+    // TODO(verwaest): Try to get object.constructor.name in this case.
+    // This requires handlification of the V8HeapExplorer.
   }
   return object->constructor_name();
 }
index 885fb46..6096c24 100644 (file)
@@ -5796,11 +5796,9 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField(
         HConstant::cast(checked_object->ActualValue())->handle(isolate()));
 
     if (object->IsJSObject()) {
-      LookupResult lookup(isolate());
-      Handle<JSObject>::cast(object)->Lookup(info->name(), &lookup);
-      Handle<Object> value(lookup.GetLazyValue(), isolate());
-
-      DCHECK(!value->IsTheHole());
+      LookupIterator it(object, info->name(), LookupIterator::CHECK_PROPERTY);
+      Handle<Object> value = JSObject::GetDataProperty(&it);
+      CHECK(it.IsFound());
       return New<HConstant>(value);
     }
   }
@@ -10695,10 +10693,10 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
         !current_info()->global_object()->IsAccessCheckNeeded()) {
       Handle<String> name = proxy->name();
       Handle<GlobalObject> global(current_info()->global_object());
-      LookupResult lookup(isolate());
-      global->Lookup(name, &lookup);
-      if (lookup.IsNormal() && lookup.GetValue()->IsJSFunction()) {
-        Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue()));
+      LookupIterator it(global, name, LookupIterator::CHECK_PROPERTY);
+      Handle<Object> value = JSObject::GetDataProperty(&it);
+      if (it.IsFound() && value->IsJSFunction()) {
+        Handle<JSFunction> candidate = Handle<JSFunction>::cast(value);
         // If the function is in new space we assume it's more likely to
         // change and thus prefer the general IC code.
         if (!isolate()->heap()->InNewSpace(*candidate)) {
index 33c0964..b080a31 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -1557,12 +1557,13 @@ Handle<Code> StoreIC::CompileStoreHandler(LookupResult* lookup,
         DCHECK(holder.is_identical_to(receiver));
         return isolate()->builtins()->StoreIC_Normal();
       case CALLBACKS: {
-        Handle<Object> callback(lookup->GetCallbackObject(), isolate());
+        if (!holder->HasFastProperties()) break;
+        Handle<Object> callback(lookup->GetValueFromMap(holder->map()),
+                                isolate());
         if (callback->IsExecutableAccessorInfo()) {
           Handle<ExecutableAccessorInfo> info =
               Handle<ExecutableAccessorInfo>::cast(callback);
           if (v8::ToCData<Address>(info->setter()) == 0) break;
-          if (!holder->HasFastProperties()) break;
           if (!ExecutableAccessorInfo::IsCompatibleReceiverType(
                   isolate(), info, receiver_type())) {
             break;
@@ -1574,8 +1575,6 @@ Handle<Code> StoreIC::CompileStoreHandler(LookupResult* lookup,
           Handle<Object> setter(
               Handle<AccessorPair>::cast(callback)->setter(), isolate());
           if (!setter->IsJSFunction()) break;
-          if (holder->IsGlobalObject()) break;
-          if (!holder->HasFastProperties()) break;
           Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
           CallOptimization call_optimization(function);
           NamedStoreHandlerCompiler compiler(isolate(), receiver_type(),
index e8c3838..e496163 100644 (file)
@@ -143,28 +143,35 @@ MaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
 Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object,
                                          Handle<Name> key) {
   LookupIterator it(object, key, LookupIterator::CHECK_DERIVED_PROPERTY);
-  for (; it.IsFound(); it.Next()) {
-    switch (it.state()) {
+  return GetDataProperty(&it);
+}
+
+
+Handle<Object> JSObject::GetDataProperty(LookupIterator* it) {
+  for (; it->IsFound(); it->Next()) {
+    switch (it->state()) {
       case LookupIterator::NOT_FOUND:
       case LookupIterator::ACCESS_CHECK:
       case LookupIterator::INTERCEPTOR:
         UNREACHABLE();
       case LookupIterator::JSPROXY:
-        return it.isolate()->factory()->undefined_value();
+        it->NotFound();
+        return it->isolate()->factory()->undefined_value();
       case LookupIterator::PROPERTY:
-        if (!it.HasProperty()) continue;
-        switch (it.property_kind()) {
+        if (!it->HasProperty()) continue;
+        switch (it->property_kind()) {
           case LookupIterator::DATA:
-            return it.GetDataValue();
+            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.
-            return it.isolate()->factory()->undefined_value();
+            it->NotFound();
+            return it->isolate()->factory()->undefined_value();
         }
     }
   }
-  return it.isolate()->factory()->undefined_value();
+  return it->isolate()->factory()->undefined_value();
 }
 
 
@@ -647,17 +654,6 @@ MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
 }
 
 
-Object* JSObject::GetNormalizedProperty(const LookupResult* result) {
-  DCHECK(!HasFastProperties());
-  Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
-  if (IsGlobalObject()) {
-    value = PropertyCell::cast(value)->value();
-  }
-  DCHECK(!value->IsPropertyCell() && !value->IsCell());
-  return value;
-}
-
-
 void JSObject::SetNormalizedProperty(Handle<JSObject> object,
                                      Handle<Name> name,
                                      Handle<Object> value,
@@ -4766,12 +4762,11 @@ Object* JSObject::GetHiddenPropertiesHashTable() {
     }
   } else {
     Isolate* isolate = GetIsolate();
-    LookupResult result(isolate);
-    LookupOwnRealNamedProperty(isolate->factory()->hidden_string(), &result);
-    if (result.IsFound()) {
-      DCHECK(result.IsNormal());
-      DCHECK(result.holder() == this);
-      return GetNormalizedProperty(&result);
+    LookupIterator it(handle(this), isolate->factory()->hidden_string(),
+                      LookupIterator::CHECK_PROPERTY);
+    if (it.IsFound() && it.HasProperty()) {
+      DCHECK_EQ(LookupIterator::DATA, it.property_kind());
+      return *it.GetDataValue();
     }
     return GetHeap()->undefined_value();
   }
index 92d5ab5..927782d 100644 (file)
@@ -2154,10 +2154,6 @@ class JSObject: public JSReceiver {
   // or returns false if such a map is not yet available.
   static bool TryMigrateInstance(Handle<JSObject> instance);
 
-  // Retrieve a value in a normalized object given a lookup result.
-  // Handles the special representation of JS global objects.
-  Object* GetNormalizedProperty(const LookupResult* result);
-
   // Sets the property value in a normalized object given (key, value, details).
   // Handles the special representation of JS global objects.
   static void SetNormalizedProperty(Handle<JSObject> object,
@@ -2480,6 +2476,7 @@ class JSObject: public JSReceiver {
 
   static Handle<Object> GetDataProperty(Handle<JSObject> object,
                                         Handle<Name> key);
+  static Handle<Object> GetDataProperty(LookupIterator* it);
 
   DECLARE_CAST(JSObject)
 
index f1378ec..9688396 100644 (file)
@@ -34,8 +34,7 @@ OStream& operator<<(OStream& os, const LookupResult& r) {
       return os << " -type = normal\n"
                 << " -entry = " << r.GetDictionaryEntry() << "\n";
     case CONSTANT:
-      return os << " -type = constant\n"
-                << " -value:\n" << Brief(r.GetConstant()) << "\n";
+      return os << " -type = constant\n";
     case FIELD:
       os << " -type = field\n"
          << " -index = " << r.GetFieldIndex().property_index() << "\n"
@@ -43,8 +42,7 @@ OStream& operator<<(OStream& os, const LookupResult& r) {
       r.GetFieldType()->PrintTo(os);
       return os << "\n";
     case CALLBACKS:
-      return os << " -type = call backs\n"
-                << " -callback object:\n" << Brief(r.GetCallbackObject());
+      return os << " -type = call backs\n";
     case HANDLER:
       return os << " -type = lookup proxy\n";
     case INTERCEPTOR:
index 272a0a5..a1e8011 100644 (file)
@@ -146,10 +146,14 @@ class LookupResult V8_FINAL BASE_EMBEDDED {
       case FIELD:
         return value->FitsRepresentation(representation()) &&
             GetFieldType()->NowContains(value);
-      case CONSTANT:
-        DCHECK(GetConstant() != *value ||
+      case CONSTANT: {
+        Map* map =
+            lookup_type_ == DESCRIPTOR_TYPE ? holder_->map() : transition_;
+        Object* constant = GetConstantFromMap(map);
+        DCHECK(constant != *value ||
                value->FitsRepresentation(representation()));
-        return GetConstant() == *value;
+        return constant == *value;
+      }
       case CALLBACKS:
       case HANDLER:
       case INTERCEPTOR:
@@ -262,10 +266,6 @@ class LookupResult V8_FINAL BASE_EMBEDDED {
     return IsDescriptorOrDictionary() && type() == CONSTANT;
   }
 
-  bool IsConstantFunction() const {
-    return IsConstant() && GetConstant()->IsJSFunction();
-  }
-
   bool IsDontDelete() const { return details_.IsDontDelete(); }
   bool IsDontEnum() const { return details_.IsDontEnum(); }
   bool IsFound() const { return lookup_type_ != NOT_FOUND; }
@@ -281,76 +281,9 @@ class LookupResult V8_FINAL BASE_EMBEDDED {
     return IsFound() && !IsTransition();
   }
 
-  bool IsDataProperty() const {
-    switch (lookup_type_) {
-      case NOT_FOUND:
-      case TRANSITION_TYPE:
-      case HANDLER_TYPE:
-      case INTERCEPTOR_TYPE:
-        return false;
-
-      case DESCRIPTOR_TYPE:
-      case DICTIONARY_TYPE:
-        switch (type()) {
-          case FIELD:
-          case NORMAL:
-          case CONSTANT:
-            return true;
-          case CALLBACKS: {
-            Object* callback = GetCallbackObject();
-            DCHECK(!callback->IsForeign());
-            return callback->IsAccessorInfo();
-          }
-          case HANDLER:
-          case INTERCEPTOR:
-          case NONEXISTENT:
-            UNREACHABLE();
-            return false;
-        }
-    }
-    UNREACHABLE();
-    return false;
-  }
-
   bool IsCacheable() const { return cacheable_; }
   void DisallowCaching() { cacheable_ = false; }
 
-  Object* GetLazyValue() const {
-    switch (lookup_type_) {
-      case NOT_FOUND:
-      case TRANSITION_TYPE:
-      case HANDLER_TYPE:
-      case INTERCEPTOR_TYPE:
-        return isolate()->heap()->the_hole_value();
-
-      case DESCRIPTOR_TYPE:
-      case DICTIONARY_TYPE:
-        switch (type()) {
-          case FIELD:
-            return holder()->RawFastPropertyAt(GetFieldIndex());
-          case NORMAL: {
-            Object* value = holder()->property_dictionary()->ValueAt(
-                GetDictionaryEntry());
-            if (holder()->IsGlobalObject()) {
-              value = PropertyCell::cast(value)->value();
-            }
-            return value;
-          }
-          case CONSTANT:
-            return GetConstant();
-          case CALLBACKS:
-            return isolate()->heap()->the_hole_value();
-          case HANDLER:
-          case INTERCEPTOR:
-          case NONEXISTENT:
-            UNREACHABLE();
-            return NULL;
-        }
-    }
-    UNREACHABLE();
-    return NULL;
-  }
-
   Map* GetTransitionTarget() const {
     DCHECK(IsTransition());
     return transition_;
@@ -384,42 +317,11 @@ class LookupResult V8_FINAL BASE_EMBEDDED {
     return number_;
   }
 
-  JSFunction* GetConstantFunction() const {
-    DCHECK(type() == CONSTANT);
-    return JSFunction::cast(GetValue());
-  }
-
   Object* GetConstantFromMap(Map* map) const {
     DCHECK(type() == CONSTANT);
     return GetValueFromMap(map);
   }
 
-  JSFunction* GetConstantFunctionFromMap(Map* map) const {
-    return JSFunction::cast(GetConstantFromMap(map));
-  }
-
-  Object* GetConstant() const {
-    DCHECK(type() == CONSTANT);
-    return GetValue();
-  }
-
-  Object* GetCallbackObject() const {
-    DCHECK(!IsTransition());
-    DCHECK(type() == CALLBACKS);
-    return GetValue();
-  }
-
-  Object* GetValue() const {
-    if (lookup_type_ == DESCRIPTOR_TYPE) {
-      return GetValueFromMap(holder()->map());
-    } else if (lookup_type_ == TRANSITION_TYPE) {
-      return GetValueFromMap(transition_);
-    }
-    // In the dictionary case, the data is held in the value field.
-    DCHECK(lookup_type_ == DICTIONARY_TYPE);
-    return holder()->GetNormalizedProperty(this);
-  }
-
   Object* GetValueFromMap(Map* map) const {
     DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
            lookup_type_ == TRANSITION_TYPE);
index a13a6e5..50ce753 100644 (file)
@@ -1981,10 +1981,9 @@ THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) {
   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
   i::LookupResult lookup(i_isolate);
   i::Handle<i::String> name(v8::Utils::OpenHandle(*v8_str("length")));
-  a->LookupOwnRealNamedProperty(name, &lookup);
-  CHECK(lookup.IsPropertyCallbacks());
-  i::Handle<i::Object> callback(lookup.GetCallbackObject(), i_isolate);
-  CHECK(callback->IsExecutableAccessorInfo());
+  i::LookupIterator it(a, name, i::LookupIterator::CHECK_PROPERTY);
+  CHECK(it.HasProperty());
+  CHECK(it.GetAccessors()->IsExecutableAccessorInfo());
 }
 
 
index e456323..94bec31 100644 (file)
@@ -1863,12 +1863,16 @@ TEST(GetConstructorName) {
       "Constructor2", i::V8HeapExplorer::GetConstructorName(*js_obj2)));
   v8::Local<v8::Object> obj3 = js_global->Get(v8_str("obj3")).As<v8::Object>();
   i::Handle<i::JSObject> js_obj3 = v8::Utils::OpenHandle(*obj3);
-  CHECK_EQ(0, StringCmp(
-      "Constructor3", i::V8HeapExplorer::GetConstructorName(*js_obj3)));
+  // TODO(verwaest): Restore to Constructor3 once supported by the
+  // heap-snapshot-generator.
+  CHECK_EQ(
+      0, StringCmp("Object", i::V8HeapExplorer::GetConstructorName(*js_obj3)));
   v8::Local<v8::Object> obj4 = js_global->Get(v8_str("obj4")).As<v8::Object>();
   i::Handle<i::JSObject> js_obj4 = v8::Utils::OpenHandle(*obj4);
-  CHECK_EQ(0, StringCmp(
-      "Constructor4", i::V8HeapExplorer::GetConstructorName(*js_obj4)));
+  // TODO(verwaest): Restore to Constructor4 once supported by the
+  // heap-snapshot-generator.
+  CHECK_EQ(
+      0, StringCmp("Object", i::V8HeapExplorer::GetConstructorName(*js_obj4)));
   v8::Local<v8::Object> obj5 = js_global->Get(v8_str("obj5")).As<v8::Object>();
   i::Handle<i::JSObject> js_obj5 = v8::Utils::OpenHandle(*obj5);
   CHECK_EQ(0, StringCmp(