Revision: 16275
Author:   [email protected]
Date:     Thu Aug 22 13:43:06 2013 UTC
Log:      Remove special case code for generalizing constants to fields.

[email protected]

Review URL: https://chromiumcodereview.appspot.com/22911018
http://code.google.com/p/v8/source/detail?r=16275

Modified:
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/ic.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/property.h
 /branches/bleeding_edge/src/runtime.cc

=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Tue Aug 20 13:55:52 2013 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu Aug 22 13:43:06 2013 UTC
@@ -1143,12 +1143,12 @@
                            JSObject::SetLocalPropertyIgnoreAttributes(
                                result, factory->length_string(),
                                factory->undefined_value(), DONT_ENUM,
- Object::FORCE_TAGGED, JSReceiver::FORCE_FIELD));
+                               Object::FORCE_TAGGED, FORCE_FIELD));
     CHECK_NOT_EMPTY_HANDLE(isolate,
                            JSObject::SetLocalPropertyIgnoreAttributes(
                                result, factory->callee_string(),
                                factory->undefined_value(), DONT_ENUM,
- Object::FORCE_TAGGED, JSReceiver::FORCE_FIELD));
+                               Object::FORCE_TAGGED, FORCE_FIELD));

 #ifdef DEBUG
     LookupResult lookup(isolate);
=======================================
--- /branches/bleeding_edge/src/ic.cc   Thu Aug 22 12:16:00 2013 UTC
+++ /branches/bleeding_edge/src/ic.cc   Thu Aug 22 13:43:06 2013 UTC
@@ -1615,7 +1615,8 @@
   if (!value->FitsRepresentation(target_details.representation())) {
     Handle<Map> target(lookup->GetTransitionMapFromMap(receiver->map()));
     Map::GeneralizeRepresentation(
-        target, target->LastAdded(), value->OptimalRepresentation());
+        target, target->LastAdded(),
+        value->OptimalRepresentation(), FORCE_FIELD);
// Lookup the transition again since the transition tree may have changed
     // entirely by the migration above.
     receiver->map()->LookupTransition(*holder, *name, lookup);
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Thu Aug 22 12:16:00 2013 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Thu Aug 22 13:43:06 2013 UTC
@@ -1569,7 +1569,7 @@
   // transition that matches the object. This achieves what is needed.
   Map* original_map = map();
   MaybeObject* maybe_result = GeneralizeFieldRepresentation(
-      0, Representation::None());
+      0, Representation::None(), ALLOW_AS_CONSTANT);
   JSObject* result;
   if (FLAG_trace_migration && maybe_result->To(&result)) {
     PrintInstanceMigration(stdout, original_map, result->map());
@@ -2361,6 +2361,7 @@


 int DescriptorArray::GetFieldIndex(int descriptor_number) {
+  ASSERT(GetDetails(descriptor_number).type() == FIELD);
   return GetDetails(descriptor_number).field_index();
 }

=======================================
--- /branches/bleeding_edge/src/objects.cc      Tue Aug 20 10:52:23 2013 UTC
+++ /branches/bleeding_edge/src/objects.cc      Thu Aug 22 13:43:06 2013 UTC
@@ -1450,19 +1450,31 @@


 void Map::PrintGeneralization(FILE* file,
+                              const char* reason,
                               int modify_index,
                               int split,
                               int descriptors,
+                              bool constant_to_field,
                               Representation old_representation,
                               Representation new_representation) {
   PrintF(file, "[generalizing ");
   constructor_name()->PrintOn(file);
   PrintF(file, "] ");
String::cast(instance_descriptors()->GetKey(modify_index))->PrintOn(file);
-  PrintF(file, ":%s->%s (+%i maps) [",
-         old_representation.Mnemonic(),
-         new_representation.Mnemonic(),
-         descriptors - split);
+  if (constant_to_field) {
+    PrintF(file, ":c->f");
+  } else {
+    PrintF(file, ":%s->%s",
+           old_representation.Mnemonic(),
+           new_representation.Mnemonic());
+  }
+  PrintF(file, " (");
+  if (strlen(reason) > 0) {
+    PrintF(file, "%s", reason);
+  } else {
+    PrintF(file, "+%i maps", descriptors - split);
+  }
+  PrintF(file, ") [");
   JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
   PrintF(file, "]\n");
 }
@@ -1988,7 +2000,7 @@
   ConstantDescriptor d(name, constant, attributes);

   TransitionFlag flag =
-      // Do not add transitions to  global objects.
+      // Do not add transitions to global objects.
       (IsGlobalObject() ||
       // Don't add transitions to special properties with non-trivial
       // attributes.
@@ -2188,55 +2200,6 @@
   PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
   return SetNormalizedProperty(name, value, new_details);
 }
-
-
-MaybeObject* JSObject::ConvertTransitionToMapTransition(
-    int transition_index,
-    Name* name,
-    Object* new_value,
-    PropertyAttributes attributes) {
-  Map* old_map = map();
-  Map* old_target = old_map->GetTransition(transition_index);
-  Object* result;
-
-  MaybeObject* maybe_result = ConvertDescriptorToField(
-      name, new_value, attributes, OMIT_TRANSITION_KEEP_REPRESENTATIONS);
-  if (!maybe_result->To(&result)) return maybe_result;
-
-  if (!HasFastProperties()) return result;
-
-  // This method should only be used to convert existing transitions.
-  Map* new_map = map();
-
-  // TODO(verwaest): From here on we lose existing map transitions, causing
-  // invalid back pointers. This will change once we can store multiple
-  // transitions with the same key.
-  bool owned_descriptors = old_map->owns_descriptors();
-  if (owned_descriptors ||
- old_target->instance_descriptors() == old_map->instance_descriptors()) { - // Since the conversion above generated a new fast map with an additional - // property which can be shared as well, install this descriptor pointer
-    // along the entire chain of smaller maps.
-    Map* map;
-    DescriptorArray* new_descriptors = new_map->instance_descriptors();
-    DescriptorArray* old_descriptors = old_map->instance_descriptors();
-    for (Object* current = old_map;
-         !current->IsUndefined();
-         current = map->GetBackPointer()) {
-      map = Map::cast(current);
-      if (map->instance_descriptors() != old_descriptors) break;
-      map->SetEnumLength(Map::kInvalidEnumCache);
-      map->set_instance_descriptors(new_descriptors);
-    }
-    old_map->set_owns_descriptors(false);
-  }
-
-  old_target->DeprecateTransitionTree();
-
-  old_map->SetTransition(transition_index, new_map);
-  new_map->SetBackPointer(old_map);
-  return result;
-}


 MaybeObject* JSObject::ConvertDescriptorToField(Name* name,
@@ -2491,10 +2454,11 @@

 MaybeObject* JSObject::GeneralizeFieldRepresentation(
     int modify_index,
-    Representation new_representation) {
+    Representation new_representation,
+    StoreMode store_mode) {
   Map* new_map;
-  MaybeObject* maybe_new_map =
-      map()->GeneralizeRepresentation(modify_index, new_representation);
+  MaybeObject* maybe_new_map = map()->GeneralizeRepresentation(
+      modify_index, new_representation, store_mode);
   if (!maybe_new_map->To(&new_map)) return maybe_new_map;
   if (map() == new_map) return this;

@@ -2512,16 +2476,39 @@
 }


-MaybeObject* Map::CopyGeneralizeAllRepresentations() {
+MaybeObject* Map::CopyGeneralizeAllRepresentations(
+    int modify_index,
+    StoreMode store_mode,
+    const char* reason) {
   Map* new_map;
   MaybeObject* maybe_map = this->Copy();
   if (!maybe_map->To(&new_map)) return maybe_map;

-  new_map->instance_descriptors()->InitializeRepresentations(
-      Representation::Tagged());
+  DescriptorArray* descriptors = new_map->instance_descriptors();
+  descriptors->InitializeRepresentations(Representation::Tagged());
+
+ // Unless the instance is being migrated, ensure that modify_index is a field.
+  PropertyDetails details = descriptors->GetDetails(modify_index);
+  if (store_mode == FORCE_FIELD && details.type() != FIELD) {
+    FieldDescriptor d(descriptors->GetKey(modify_index),
+                      new_map->NumberOfFields(),
+                      details.attributes(),
+                      Representation::Tagged());
+    d.SetSortedKeyIndex(details.pointer());
+    descriptors->Set(modify_index, &d);
+    int unused_property_fields = new_map->unused_property_fields() - 1;
+    if (unused_property_fields < 0) {
+      unused_property_fields += JSObject::kFieldsAdded;
+    }
+    new_map->set_unused_property_fields(unused_property_fields);
+  }
+
   if (FLAG_trace_generalization) {
-    PrintF("failed generalization %p -> %p\n",
-           static_cast<void*>(this), static_cast<void*>(new_map));
+    PrintGeneralization(stdout, reason, modify_index,
+                        new_map->NumberOfOwnDescriptors(),
+                        new_map->NumberOfOwnDescriptors(),
+ details.type() == CONSTANT && store_mode == FORCE_FIELD, + Representation::Tagged(), Representation::Tagged());
   }
   return new_map;
 }
@@ -2666,7 +2653,8 @@
// - Otherwise, invalidate the outdated transition target from |updated|, and // replace its transition tree with a new branch for the updated descriptors.
 MaybeObject* Map::GeneralizeRepresentation(int modify_index,
- Representation new_representation) { + Representation new_representation,
+                                           StoreMode store_mode) {
   Map* old_map = this;
   DescriptorArray* old_descriptors = old_map->instance_descriptors();
   Representation old_representation =
@@ -2688,38 +2676,45 @@

   // Check the state of the root map.
   if (!old_map->EquivalentToForTransition(root_map)) {
-    return CopyGeneralizeAllRepresentations();
+    return CopyGeneralizeAllRepresentations(
+        modify_index, store_mode, "not equivalent");
   }

   int verbatim = root_map->NumberOfOwnDescriptors();

+  if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
+    return CopyGeneralizeAllRepresentations(
+        modify_index, store_mode, "root modification");
+  }
+
   Map* updated = root_map->FindUpdatedMap(
       verbatim, descriptors, old_descriptors);
-  if (updated == NULL) return CopyGeneralizeAllRepresentations();
+  if (updated == NULL) {
+    return CopyGeneralizeAllRepresentations(
+        modify_index, store_mode, "incompatible");
+  }

   DescriptorArray* updated_descriptors = updated->instance_descriptors();

   int valid = updated->NumberOfOwnDescriptors();
+
+ // Directly change the map if the target map is more general. Ensure that the
+  // target type of the modify_index is a FIELD, unless we are migrating.
   if (updated_descriptors->IsMoreGeneralThan(
-          verbatim, valid, descriptors, old_descriptors)) {
+          verbatim, valid, descriptors, old_descriptors) &&
+      (store_mode == ALLOW_AS_CONSTANT ||
+       updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
     Representation updated_representation =
         updated_descriptors->GetDetails(modify_index).representation();
-    if (new_representation.fits_into(updated_representation)) {
-      if (FLAG_trace_generalization &&
-          !(modify_index == 0 && new_representation.IsNone())) {
- PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
-        PrintGeneralization(stdout, modify_index, descriptors, descriptors,
-                            old_details.representation(),
-                            updated_representation);
-      }
-      return updated;
-    }
+ if (new_representation.fits_into(updated_representation)) return updated;
   }

   DescriptorArray* new_descriptors;
   MaybeObject* maybe_descriptors = updated_descriptors->Merge(
-      verbatim, valid, descriptors, old_descriptors);
+ verbatim, valid, descriptors, modify_index, store_mode, old_descriptors);
   if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
+  ASSERT(store_mode == ALLOW_AS_CONSTANT ||
+         new_descriptors->GetDetails(modify_index).type() == FIELD);

   old_representation =
       new_descriptors->GetDetails(modify_index).representation();
@@ -2741,10 +2736,12 @@
   split_map->DeprecateTarget(
       old_descriptors->GetKey(descriptor), new_descriptors);

-  if (FLAG_trace_generalization &&
-      !(modify_index == 0 && new_representation.IsNone())) {
-    PrintGeneralization(stdout, modify_index, descriptor, descriptors,
-                        old_representation, updated_representation);
+  if (FLAG_trace_generalization) {
+    PrintGeneralization(
+        stdout, "", modify_index, descriptor, descriptors,
+        old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
+            store_mode == FORCE_FIELD,
+        old_representation, updated_representation);
   }

   Map* new_map = split_map;
@@ -3782,13 +3779,91 @@

 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map,
                                           int modify_index,
-                                          Representation representation) {
+                                          Representation representation,
+                                          StoreMode store_mode) {
   CALL_HEAP_FUNCTION(
       map->GetIsolate(),
-      map->GeneralizeRepresentation(modify_index, representation),
+ map->GeneralizeRepresentation(modify_index, representation, store_mode),
       Map);
 }

+
+static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup,
+                                               Handle<Name> name,
+                                               Handle<Object> value,
+ PropertyAttributes attributes) {
+  Map* transition_map = lookup->GetTransitionTarget();
+  int descriptor = transition_map->LastAdded();
+
+  DescriptorArray* descriptors = transition_map->instance_descriptors();
+  PropertyDetails details = descriptors->GetDetails(descriptor);
+
+  if (details.type() == CALLBACKS || attributes != details.attributes()) {
+    return lookup->holder()->ConvertDescriptorToField(
+        *name, *value, attributes);
+  }
+
+  // Keep the target CONSTANT if the same value is stored.
+  // TODO(verwaest): Also support keeping the placeholder
+  // (value->IsUninitialized) as constant.
+  if (details.type() == CONSTANT &&
+      descriptors->GetValue(descriptor) == *value) {
+    lookup->holder()->set_map(transition_map);
+    return *value;
+  }
+
+  Representation representation = details.representation();
+
+  if (!value->FitsRepresentation(representation) ||
+      details.type() == CONSTANT) {
+    MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
+        descriptor, value->OptimalRepresentation(), FORCE_FIELD);
+    if (!maybe_map->To(&transition_map)) return maybe_map;
+    Object* back = transition_map->GetBackPointer();
+    if (back->IsMap()) {
+      MaybeObject* maybe_failure =
+          lookup->holder()->MigrateToMap(Map::cast(back));
+      if (maybe_failure->IsFailure()) return maybe_failure;
+    }
+    descriptors = transition_map->instance_descriptors();
+    representation = descriptors->GetDetails(descriptor).representation();
+  }
+
+  int field_index = descriptors->GetFieldIndex(descriptor);
+  return lookup->holder()->AddFastPropertyUsingMap(
+      transition_map, *name, *value, field_index, representation);
+}
+
+
+static MaybeObject* SetPropertyToField(LookupResult* lookup,
+                                       Handle<Name> name,
+                                       Handle<Object> value) {
+  Representation representation = lookup->representation();
+  if (!value->FitsRepresentation(representation) ||
+      lookup->type() == CONSTANT) {
+    MaybeObject* maybe_failure =
+        lookup->holder()->GeneralizeFieldRepresentation(
+            lookup->GetDescriptorIndex(),
+            value->OptimalRepresentation(),
+            FORCE_FIELD);
+    if (maybe_failure->IsFailure()) return maybe_failure;
+ DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
+    int descriptor = lookup->GetDescriptorIndex();
+    representation = desc->GetDetails(descriptor).representation();
+  }
+
+  if (FLAG_track_double_fields && representation.IsDouble()) {
+ HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
+        lookup->GetFieldIndex().field_index()));
+    storage->set_value(value->Number());
+    return *value;
+  }
+
+  lookup->holder()->FastPropertyAtPut(
+      lookup->GetFieldIndex().field_index(), *value);
+  return *value;
+}
+

 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
                                             Name* name_raw,
@@ -3878,37 +3953,13 @@
     case NORMAL:
       result = lookup->holder()->SetNormalizedProperty(lookup, *value);
       break;
-    case FIELD: {
-      Representation representation = lookup->representation();
-      if (!value->FitsRepresentation(representation)) {
-        MaybeObject* maybe_failure =
-            lookup->holder()->GeneralizeFieldRepresentation(
- lookup->GetDescriptorIndex(), value->OptimalRepresentation());
-        if (maybe_failure->IsFailure()) return maybe_failure;
- DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
-        int descriptor = lookup->GetDescriptorIndex();
-        representation = desc->GetDetails(descriptor).representation();
-      }
-      if (FLAG_track_double_fields && representation.IsDouble()) {
-        HeapNumber* storage =
-            HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
-                lookup->GetFieldIndex().field_index()));
-        storage->set_value(value->Number());
-        result = *value;
-        break;
-      }
-      lookup->holder()->FastPropertyAtPut(
-          lookup->GetFieldIndex().field_index(), *value);
-      result = *value;
+    case FIELD:
+      result = SetPropertyToField(lookup, name, value);
       break;
-    }
     case CONSTANT:
       // Only replace the constant if necessary.
       if (*value == lookup->GetConstant()) return *value;
-      // Preserve the attributes of this existing property.
-      attributes = lookup->GetAttributes();
-      result = lookup->holder()->ConvertDescriptorToField(
-          *name, *value, attributes);
+      result = SetPropertyToField(lookup, name, value);
       break;
     case CALLBACKS: {
       Object* callback_object = lookup->GetCallbackObject();
@@ -3920,55 +3971,7 @@
           *name, *value, attributes, strict_mode);
       break;
     case TRANSITION: {
-      Map* transition_map = lookup->GetTransitionTarget();
-      int descriptor = transition_map->LastAdded();
-
- DescriptorArray* descriptors = transition_map->instance_descriptors();
-      PropertyDetails details = descriptors->GetDetails(descriptor);
-
-      if (details.type() == FIELD) {
-        if (attributes == details.attributes()) {
-          Representation representation = details.representation();
-          if (!value->FitsRepresentation(representation)) {
- MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
-                descriptor, value->OptimalRepresentation());
-            if (!maybe_map->To(&transition_map)) return maybe_map;
-            Object* back = transition_map->GetBackPointer();
-            if (back->IsMap()) {
-              MaybeObject* maybe_failure =
-                  lookup->holder()->MigrateToMap(Map::cast(back));
-              if (maybe_failure->IsFailure()) return maybe_failure;
-            }
-            DescriptorArray* desc = transition_map->instance_descriptors();
-            int descriptor = transition_map->LastAdded();
-            representation = desc->GetDetails(descriptor).representation();
-          }
-          int field_index = descriptors->GetFieldIndex(descriptor);
-          result = lookup->holder()->AddFastPropertyUsingMap(
-              transition_map, *name, *value, field_index, representation);
-        } else {
-          result = lookup->holder()->ConvertDescriptorToField(
-              *name, *value, attributes);
-        }
-      } else if (details.type() == CALLBACKS) {
-        result = lookup->holder()->ConvertDescriptorToField(
-            *name, *value, attributes);
-      } else {
-        ASSERT(details.type() == CONSTANT);
-
-        Object* constant = descriptors->GetValue(descriptor);
-        if (constant == *value) {
-          // If the same constant function is being added we can simply
-          // transition to the target map.
-          lookup->holder()->set_map(transition_map);
-          result = constant;
-        } else {
- // Otherwise, replace with a map transition to a new map with a FIELD,
-          // even if the value is a constant function.
-          result = lookup->holder()->ConvertTransitionToMapTransition(
-              lookup->GetTransitionIndex(), *name, *value, attributes);
-        }
-      }
+      result = SetPropertyUsingTransition(lookup, name, value, attributes);
       break;
     }
     case HANDLER:
@@ -4088,87 +4091,24 @@
       result = self->SetNormalizedProperty(*name, *value, details);
       break;
     }
-    case FIELD: {
-      Representation representation = lookup.representation();
-      Representation value_representation =
-          value->OptimalRepresentation(value_type);
-      if (value_representation.IsNone()) break;
-      if (!value_representation.fits_into(representation)) {
-        MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation(
-            lookup.GetDescriptorIndex(), value_representation);
-        if (maybe_failure->IsFailure()) return maybe_failure;
-        DescriptorArray* desc = self->map()->instance_descriptors();
-        int descriptor = lookup.GetDescriptorIndex();
-        representation = desc->GetDetails(descriptor).representation();
-      }
-      if (FLAG_track_double_fields && representation.IsDouble()) {
-        HeapNumber* storage =
-            HeapNumber::cast(self->RawFastPropertyAt(
-                lookup.GetFieldIndex().field_index()));
-        storage->set_value(value->Number());
-        result = *value;
-        break;
-      }
- self->FastPropertyAtPut(lookup.GetFieldIndex().field_index(), *value);
-      result = *value;
+    case FIELD:
+      if (value->IsUninitialized()) break;
+      result = SetPropertyToField(&lookup, name, value);
       break;
-    }
     case CONSTANT:
-      // Only replace the function if necessary.
-      if (*value != lookup.GetConstant()) {
-        // Preserve the attributes of this existing property.
-        attributes = lookup.GetAttributes();
-        result = self->ConvertDescriptorToField(*name, *value, attributes);
-      }
+      // Only replace the constant if necessary.
+      if (*value == lookup.GetConstant()) return *value;
+      if (value->IsUninitialized()) break;
+      result = SetPropertyToField(&lookup, name, value);
       break;
     case CALLBACKS:
     case INTERCEPTOR:
       // Override callback in clone
       result = self->ConvertDescriptorToField(*name, *value, attributes);
       break;
-    case TRANSITION: {
-      Map* transition_map = lookup.GetTransitionTarget();
-      int descriptor = transition_map->LastAdded();
-
- DescriptorArray* descriptors = transition_map->instance_descriptors();
-      PropertyDetails details = descriptors->GetDetails(descriptor);
-
-      if (details.type() == FIELD) {
-        if (attributes == details.attributes()) {
-          Representation representation = details.representation();
-          Representation value_representation =
-              value->OptimalRepresentation(value_type);
-          if (!value_representation.fits_into(representation)) {
- MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
-                descriptor, value_representation);
-            if (!maybe_map->To(&transition_map)) return maybe_map;
-            Object* back = transition_map->GetBackPointer();
-            if (back->IsMap()) {
- MaybeObject* maybe_failure = self->MigrateToMap(Map::cast(back));
-              if (maybe_failure->IsFailure()) return maybe_failure;
-            }
-            DescriptorArray* desc = transition_map->instance_descriptors();
-            int descriptor = transition_map->LastAdded();
-            representation = desc->GetDetails(descriptor).representation();
-          }
-          int field_index = descriptors->GetFieldIndex(descriptor);
-          result = self->AddFastPropertyUsingMap(
-              transition_map, *name, *value, field_index, representation);
-        } else {
- result = self->ConvertDescriptorToField(*name, *value, attributes);
-        }
-      } else if (details.type() == CALLBACKS) {
-        result = self->ConvertDescriptorToField(*name, *value, attributes);
-      } else {
-        ASSERT(details.type() == CONSTANT);
-
- // Replace transition to CONSTANT FUNCTION with a map transition to a
-        // new map with a FIELD, even if the value is a function.
-        result = self->ConvertTransitionToMapTransition(
-            lookup.GetTransitionIndex(), *name, *value, attributes);
-      }
+    case TRANSITION:
+ result = SetPropertyUsingTransition(&lookup, name, value, attributes);
       break;
-    }
     case HANDLER:
     case NONEXISTENT:
       UNREACHABLE();
@@ -6675,7 +6615,7 @@
     if (!maybe_transitions->To(&transitions)) return maybe_transitions;
     set_transitions(transitions);
     result->SetBackPointer(this);
-  } else if (flag != OMIT_TRANSITION_KEEP_REPRESENTATIONS) {
+  } else {
     descriptors->InitializeRepresentations(Representation::Tagged());
   }

@@ -7803,6 +7743,8 @@
 MaybeObject* DescriptorArray::Merge(int verbatim,
                                     int valid,
                                     int new_size,
+                                    int modify_index,
+                                    StoreMode store_mode,
                                     DescriptorArray* other) {
   ASSERT(verbatim <= valid);
   ASSERT(valid <= new_size);
@@ -7836,6 +7778,7 @@
     PropertyDetails other_details = other->GetDetails(descriptor);

     if (details.type() == FIELD || other_details.type() == FIELD ||
+        (store_mode == FORCE_FIELD && descriptor == modify_index) ||
         (details.type() == CONSTANT &&
          other_details.type() == CONSTANT &&
          GetValue(descriptor) != other->GetValue(descriptor))) {
@@ -7854,7 +7797,8 @@
   // |valid| -> |new_size|
   for (; descriptor < new_size; descriptor++) {
     PropertyDetails details = other->GetDetails(descriptor);
-    if (details.type() == FIELD) {
+    if (details.type() == FIELD ||
+        (store_mode == FORCE_FIELD && descriptor == modify_index)) {
       Name* key = other->GetKey(descriptor);
       FieldDescriptor d(key,
                         current_offset++,
=======================================
--- /branches/bleeding_edge/src/objects.h       Thu Aug 22 12:16:00 2013 UTC
+++ /branches/bleeding_edge/src/objects.h       Thu Aug 22 13:43:06 2013 UTC
@@ -232,6 +232,13 @@
 enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER };


+// Indicates whether a value can be loaded as a constant.
+enum StoreMode {
+  ALLOW_AS_CONSTANT,
+  FORCE_FIELD
+};
+
+
 // PropertyNormalizationMode is used to specify whether to keep
 // inobject properties when normalizing properties of a JSObject.
 enum PropertyNormalizationMode {
@@ -258,7 +265,6 @@
 // Indicates whether transitions can be added to a source map or not.
 enum TransitionFlag {
   INSERT_TRANSITION,
-  OMIT_TRANSITION_KEEP_REPRESENTATIONS,
   OMIT_TRANSITION
 };

@@ -1926,12 +1932,6 @@
     CERTAINLY_NOT_STORE_FROM_KEYED
   };

-  // Indicates whether a value can be loaded as a constant.
-  enum StoreMode {
-    ALLOW_AS_CONSTANT,
-    FORCE_FIELD
-  };
-
   // Internal properties (e.g. the hidden properties dictionary) might
   // be added even though the receiver is non-extensible.
   enum ExtensibilityCheck {
@@ -2522,13 +2522,6 @@
MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
   MUST_USE_RESULT MaybeObject* UpdateAllocationSite(ElementsKind to_kind);

- // Replaces an existing transition with a transition to a map with a FIELD.
-  MUST_USE_RESULT MaybeObject* ConvertTransitionToMapTransition(
-      int transition_index,
-      Name* name,
-      Object* new_value,
-      PropertyAttributes attributes);
-
   // Converts a descriptor of any other type to a real field, backed by the
   // properties array.
   MUST_USE_RESULT MaybeObject* ConvertDescriptorToField(
@@ -2540,7 +2533,8 @@
   MUST_USE_RESULT MaybeObject* MigrateToMap(Map* new_map);
   MUST_USE_RESULT MaybeObject* GeneralizeFieldRepresentation(
       int modify_index,
-      Representation new_representation);
+      Representation new_representation,
+      StoreMode store_mode);

   // Add a property to a fast-case object.
   MUST_USE_RESULT MaybeObject* AddFastProperty(
@@ -3190,6 +3184,8 @@
   MUST_USE_RESULT MaybeObject* Merge(int verbatim,
                                      int valid,
                                      int new_size,
+                                     int modify_index,
+                                     StoreMode store_mode,
                                      DescriptorArray* other);

   bool IsMoreGeneralThan(int verbatim,
@@ -5619,16 +5615,23 @@
   static Handle<Map> GeneralizeRepresentation(
       Handle<Map> map,
       int modify_index,
-      Representation new_representation);
+      Representation new_representation,
+      StoreMode store_mode);
   MUST_USE_RESULT MaybeObject* GeneralizeRepresentation(
       int modify_index,
-      Representation representation);
-  MUST_USE_RESULT MaybeObject* CopyGeneralizeAllRepresentations();
+      Representation representation,
+      StoreMode store_mode);
+  MUST_USE_RESULT MaybeObject* CopyGeneralizeAllRepresentations(
+      int modify_index,
+      StoreMode store_mode,
+      const char* reason);

   void PrintGeneralization(FILE* file,
+                           const char* reason,
                            int modify_index,
                            int split,
                            int descriptors,
+                           bool constant_to_field,
                            Representation old_representation,
                            Representation new_representation);

=======================================
--- /branches/bleeding_edge/src/property.h      Wed Jul 24 12:34:50 2013 UTC
+++ /branches/bleeding_edge/src/property.h      Thu Aug 22 13:43:06 2013 UTC
@@ -422,12 +422,10 @@

   PropertyIndex GetFieldIndex() {
     ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
-    ASSERT(IsField());
return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map()));
   }

   int GetLocalFieldIndexFromMap(Map* map) {
-    ASSERT(IsField());
     return GetFieldIndexFromMap(map) - map->inobject_properties();
   }

=======================================
--- /branches/bleeding_edge/src/runtime.cc      Thu Aug 22 13:03:40 2013 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Thu Aug 22 13:43:06 2013 UTC
@@ -290,9 +290,7 @@
     }
     Handle<Object> result;
     uint32_t element_index = 0;
-    JSReceiver::StoreMode mode = value->IsJSObject()
-        ? JSReceiver::FORCE_FIELD
-        : JSReceiver::ALLOW_AS_CONSTANT;
+    StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT;
     if (key->IsInternalizedString()) {
       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
         // Array index as string (uint32).

--
--
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/groups/opt_out.

Reply via email to