Don't create new maps in CurrentMapForDeprecated.
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 21 May 2013 11:20:24 +0000 (11:20 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 21 May 2013 11:20:24 +0000 (11:20 +0000)
R=yangguo@chromium.org

Review URL: https://chromiumcodereview.appspot.com/15358005

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

src/ast.h
src/hydrogen.cc
src/objects-inl.h
src/objects.cc
src/objects.h
src/type-info.cc

index d697da7..ad7b119 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -278,7 +278,9 @@ class SmallMapList {
   int length() const { return list_.length(); }
 
   void AddMapIfMissing(Handle<Map> map, Zone* zone) {
-    map = Map::CurrentMapForDeprecated(map);
+    Map* updated = map->CurrentMapForDeprecated();
+    if (updated == NULL) return;
+    map = Handle<Map>(updated);
     for (int i = 0; i < length(); ++i) {
       if (at(i).is_identical_to(map)) return;
     }
index a97e083..328ec32 100644 (file)
@@ -1832,7 +1832,7 @@ void HGraphBuilder::BuildCompareNil(
   } else {
     if_nil.Then();
     if_nil.Else();
-    if (types.Contains(CompareNilICStub::MONOMORPHIC_MAP)) {
+    if (!map.is_null() && types.Contains(CompareNilICStub::MONOMORPHIC_MAP)) {
       BuildCheckNonSmi(value);
       // For ICs, the map checked below is a sentinel map that gets replaced by
       // the monomorphic map when the code is used as a template to generate a
index 8c6e925..c48876b 100644 (file)
@@ -3624,12 +3624,6 @@ bool Map::CanBeDeprecated() {
 }
 
 
-Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) {
-  if (!map->is_deprecated()) return map;
-  return GeneralizeRepresentation(map, 0, Representation::Smi());
-}
-
-
 void Map::NotifyLeafMapLayoutChange() {
   dependent_code()->DeoptimizeDependentCodeGroup(
       GetIsolate(),
index 16d38a6..1e586e8 100644 (file)
@@ -2537,6 +2537,7 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
   int descriptors = old_map->NumberOfOwnDescriptors();
   Map* root_map = old_map->FindRootMap();
 
+  // Check the state of the root map.
   if (!old_map->EquivalentToForTransition(root_map)) {
     return CopyGeneralizeAllRepresentations();
   }
@@ -2547,7 +2548,6 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
       verbatim, descriptors, old_descriptors);
   if (updated == NULL) return CopyGeneralizeAllRepresentations();
 
-  // Check the state of the root map.
   DescriptorArray* updated_descriptors = updated->instance_descriptors();
 
   int valid = updated->NumberOfOwnDescriptors();
@@ -2624,6 +2624,34 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
 }
 
 
+Map* Map::CurrentMapForDeprecated() {
+  AssertNoAllocation no_allocation;
+  if (!is_deprecated()) return this;
+
+  DescriptorArray* old_descriptors = instance_descriptors();
+
+  int descriptors = NumberOfOwnDescriptors();
+  Map* root_map = FindRootMap();
+
+  // Check the state of the root map.
+  if (!EquivalentToForTransition(root_map)) return NULL;
+  int verbatim = root_map->NumberOfOwnDescriptors();
+
+  Map* updated = root_map->FindUpdatedMap(
+      verbatim, descriptors, old_descriptors);
+  if (updated == NULL) return NULL;
+
+  DescriptorArray* updated_descriptors = updated->instance_descriptors();
+  int valid = updated->NumberOfOwnDescriptors();
+  if (!updated_descriptors->IsMoreGeneralThan(
+          verbatim, valid, descriptors, old_descriptors)) {
+    return NULL;
+  }
+
+  return updated;
+}
+
+
 MaybeObject* JSObject::SetPropertyWithInterceptor(
     Name* name,
     Object* value,
index d466f65..2c31f30 100644 (file)
@@ -5377,9 +5377,8 @@ class Map: public HeapObject {
   // Returns a non-deprecated version of the input. If the input was not
   // deprecated, it is directly returned. Otherwise, the non-deprecated version
   // is found by re-transitioning from the root of the transition tree using the
-  // descriptor array of the map. New maps (and transitions) may be created if
-  // no new (more general) version exists.
-  static inline Handle<Map> CurrentMapForDeprecated(Handle<Map> map);
+  // descriptor array of the map. Returns NULL if no updated map is found.
+  Map* CurrentMapForDeprecated();
 
   MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
   MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors();
index 21dcf74..53866c1 100644 (file)
@@ -105,6 +105,8 @@ bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) {
         Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL;
     if (!preliminary_checks) return false;
     Map* map = code->FindFirstMap();
+    if (map == NULL) return false;
+    map = map->CurrentMapForDeprecated();
     return map != NULL && !CanRetainOtherContext(map, *native_context_);
   }
   return false;
@@ -136,6 +138,8 @@ bool TypeFeedbackOracle::StoreIsMonomorphicNormal(TypeFeedbackId ast_id) {
         Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL;
     if (!preliminary_checks) return false;
     Map* map = code->FindFirstMap();
+    if (map == NULL) return false;
+    map = map->CurrentMapForDeprecated();
     return map != NULL && !CanRetainOtherContext(map, *native_context_);
   }
   return false;
@@ -192,14 +196,12 @@ Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
   Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
   if (map_or_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(map_or_code);
-    Handle<Map> first_map(code->FindFirstMap());
-    ASSERT(!first_map.is_null());
-    first_map = Map::CurrentMapForDeprecated(first_map);
-    return CanRetainOtherContext(*first_map, *native_context_)
+    Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
+    return map == NULL || CanRetainOtherContext(map, *native_context_)
         ? Handle<Map>::null()
-        : first_map;
+        : Handle<Map>(map);
   }
-  return Map::CurrentMapForDeprecated(Handle<Map>::cast(map_or_code));
+  return Handle<Map>::cast(map_or_code);
 }
 
 
@@ -209,14 +211,12 @@ Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(
   Handle<Object> map_or_code = GetInfo(ast_id);
   if (map_or_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(map_or_code);
-    Handle<Map> first_map(code->FindFirstMap());
-    ASSERT(!first_map.is_null());
-    first_map = Map::CurrentMapForDeprecated(first_map);
-    return CanRetainOtherContext(*first_map, *native_context_)
+    Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
+    return map == NULL || CanRetainOtherContext(map, *native_context_)
         ? Handle<Map>::null()
-        : first_map;
+        : Handle<Map>(map);
   }
-  return Map::CurrentMapForDeprecated(Handle<Map>::cast(map_or_code));
+  return Handle<Map>::cast(map_or_code);
 }
 
 
@@ -224,10 +224,15 @@ Handle<Map> TypeFeedbackOracle::CompareNilMonomorphicReceiverType(
     TypeFeedbackId id) {
   Handle<Object> maybe_code = GetInfo(id);
   if (maybe_code->IsCode()) {
-    Map* first_map = Handle<Code>::cast(maybe_code)->FindFirstMap();
-    if (first_map != NULL) {
-      return Map::CurrentMapForDeprecated(Handle<Map>(first_map));
-    }
+    Map* map = Handle<Code>::cast(maybe_code)->FindFirstMap();
+    if (map == NULL) return Handle<Map>();
+    map = map->CurrentMapForDeprecated();
+    return map == NULL || CanRetainOtherContext(map, *native_context_)
+           ? Handle<Map>()
+           : Handle<Map>(map);
+  } else if (maybe_code->IsMap()) {
+    ASSERT(!Handle<Map>::cast(maybe_code)->is_deprecated());
+    return Handle<Map>::cast(maybe_code);
   }
   return Handle<Map>();
 }
@@ -351,8 +356,7 @@ ElementsKind TypeFeedbackOracle::GetCallNewElementsKind(CallNew* expr) {
 Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(
     ObjectLiteral::Property* prop) {
   ASSERT(ObjectLiteralStoreIsMonomorphic(prop));
-  return Map::CurrentMapForDeprecated(
-      Handle<Map>::cast(GetInfo(prop->key()->LiteralFeedbackId())));
+  return Handle<Map>::cast(GetInfo(prop->key()->LiteralFeedbackId()));
 }
 
 
@@ -431,12 +435,10 @@ Handle<Map> TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) {
   if (state != CompareIC::KNOWN_OBJECT) {
     return Handle<Map>::null();
   }
-  Handle<Map> first_map(code->FindFirstMap());
-  ASSERT(!first_map.is_null());
-  first_map = Map::CurrentMapForDeprecated(first_map);
-  return CanRetainOtherContext(*first_map, *native_context_)
+  Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
+  return map == NULL || CanRetainOtherContext(map, *native_context_)
       ? Handle<Map>::null()
-      : first_map;
+      : Handle<Map>(map);
 }
 
 
@@ -723,7 +725,8 @@ void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
               SetInfo(ast_id, static_cast<Object*>(target));
             } else if (!CanRetainOtherContext(Map::cast(map),
                                               *native_context_)) {
-              SetInfo(ast_id, map);
+              Map* feedback = Map::cast(map)->CurrentMapForDeprecated();
+              if (feedback != NULL) SetInfo(ast_id, feedback);
             }
           }
         } else {