| Index: src/objects.cc
 | 
| diff --git a/src/objects.cc b/src/objects.cc
 | 
| index 46e691a73553117cd1e4f13c40563f42706266a7..765d4d06f4e86a92a6f251f475685ef0647ae6a5 100644
 | 
| --- a/src/objects.cc
 | 
| +++ b/src/objects.cc
 | 
| @@ -2191,7 +2191,7 @@ void Map::CopyAppendCallbackDescriptors(Handle<Map> map,
 | 
|    // After this point the GC is not allowed to run anymore until the map is in a
 | 
|    // consistent state again, i.e., all the descriptors are appended and the
 | 
|    // descriptor array is trimmed to the right size.
 | 
| -  map->set_instance_descriptors(*result);
 | 
| +  Map::SetDescriptors(map, result);
 | 
|  
 | 
|    // Fill in new callback descriptors.  Process the callbacks from
 | 
|    // back to front so that the last callback with a given name takes
 | 
| @@ -2210,7 +2210,7 @@ void Map::CopyAppendCallbackDescriptors(Handle<Map> map,
 | 
|    int new_number_of_descriptors = map->NumberOfSetDescriptors();
 | 
|    // Reinstall the original descriptor array if no new elements were added.
 | 
|    if (new_number_of_descriptors == descriptor_count) {
 | 
| -    map->set_instance_descriptors(*array);
 | 
| +    Map::SetDescriptors(map, array);
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| @@ -4102,7 +4102,7 @@ MaybeObject* JSObject::PreventExtensions() {
 | 
|    // Do a map transition, other objects with this map may still
 | 
|    // be extensible.
 | 
|    Map* new_map;
 | 
| -  MaybeObject* maybe = map()->Copy(DescriptorArray::MAY_BE_SHARED);
 | 
| +  MaybeObject* maybe = map()->Copy();
 | 
|    if (!maybe->To(&new_map)) return maybe;
 | 
|  
 | 
|    new_map->set_is_extensible(false);
 | 
| @@ -4139,6 +4139,13 @@ bool JSReceiver::IsSimpleEnum() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void Map::SetDescriptors(Handle<Map> map,
 | 
| +                         Handle<DescriptorArray> descriptors) {
 | 
| +  Isolate* isolate = map->GetIsolate();
 | 
| +  CALL_HEAP_FUNCTION_VOID(isolate, map->SetDescriptors(*descriptors));
 | 
| +}
 | 
| +
 | 
| +
 | 
|  int Map::NumberOfDescribedProperties(PropertyAttributes filter) {
 | 
|    int result = 0;
 | 
|    DescriptorArray* descs = instance_descriptors();
 | 
| @@ -4877,7 +4884,8 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
 | 
|    } else {
 | 
|      ASSERT(descriptors->GetDetails(last_added).index() ==
 | 
|             descriptors->number_of_descriptors());
 | 
| -    result->set_instance_descriptors(descriptors);
 | 
| +    MaybeObject* maybe_failure = result->SetDescriptors(descriptors);
 | 
| +    if (maybe_failure->IsFailure()) return maybe_failure;
 | 
|      result->SetLastAdded(last_added);
 | 
|    }
 | 
|  
 | 
| @@ -4886,9 +4894,7 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
 | 
|      MaybeObject* maybe_transitions = AddTransition(name, result);
 | 
|      if (!maybe_transitions->To(&transitions)) return maybe_transitions;
 | 
|  
 | 
| -    MaybeObject* maybe_set = set_transitions(transitions);
 | 
| -    if (maybe_set->IsFailure()) return maybe_set;
 | 
| -
 | 
| +    set_transitions(transitions);
 | 
|      result->SetBackPointer(this);
 | 
|    }
 | 
|  
 | 
| @@ -4899,7 +4905,7 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
 | 
|  MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
 | 
|    // Create a new free-floating map only if we are not allowed to store it.
 | 
|    Map* new_map = NULL;
 | 
| -  MaybeObject* maybe_new_map = Copy(DescriptorArray::MAY_BE_SHARED);
 | 
| +  MaybeObject* maybe_new_map = Copy();
 | 
|    if (!maybe_new_map->To(&new_map)) return maybe_new_map;
 | 
|    new_map->set_elements_kind(kind);
 | 
|  
 | 
| @@ -4931,25 +4937,17 @@ MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() {
 | 
|    // array describing these properties.
 | 
|    ASSERT(constructor()->IsJSFunction());
 | 
|    JSFunction* ctor = JSFunction::cast(constructor());
 | 
| -  Map* initial_map = ctor->initial_map();
 | 
| -  DescriptorArray* initial_descriptors = initial_map->instance_descriptors();
 | 
| -  DescriptorArray* descriptors;
 | 
| -  MaybeObject* maybe_descriptors =
 | 
| -      initial_descriptors->Copy(DescriptorArray::MAY_BE_SHARED);
 | 
| -  if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
 | 
| +  Map* map = ctor->initial_map();
 | 
| +  DescriptorArray* descriptors = map->instance_descriptors();
 | 
|  
 | 
| -  int last_added = initial_map->LastAdded();
 | 
| +  int last_added = map->LastAdded();
 | 
|  
 | 
|    return CopyReplaceDescriptors(descriptors, NULL, last_added, OMIT_TRANSITION);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -MaybeObject* Map::Copy(DescriptorArray::SharedMode shared_mode) {
 | 
| -  DescriptorArray* source_descriptors = instance_descriptors();
 | 
| -  DescriptorArray* descriptors;
 | 
| -  MaybeObject* maybe_descriptors = source_descriptors->Copy(shared_mode);
 | 
| -  if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
 | 
| -
 | 
| +MaybeObject* Map::Copy() {
 | 
| +  DescriptorArray* descriptors = instance_descriptors();
 | 
|    int last_added = LastAdded();
 | 
|  
 | 
|    return CopyReplaceDescriptors(descriptors, NULL, last_added, OMIT_TRANSITION);
 | 
| @@ -4976,8 +4974,7 @@ MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
 | 
|    int new_size = old_size + 1;
 | 
|  
 | 
|    DescriptorArray* new_descriptors;
 | 
| -  MaybeObject* maybe_descriptors =
 | 
| -      DescriptorArray::Allocate(new_size, DescriptorArray::MAY_BE_SHARED);
 | 
| +  MaybeObject* maybe_descriptors = DescriptorArray::Allocate(new_size);
 | 
|    if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
 | 
|  
 | 
|    FixedArray::WhitenessWitness witness(new_descriptors);
 | 
| @@ -5038,8 +5035,7 @@ MaybeObject* Map::CopyReplaceDescriptor(Descriptor* descriptor,
 | 
|    ASSERT(key == descriptors->GetKey(insertion_index));
 | 
|  
 | 
|    DescriptorArray* new_descriptors;
 | 
| -  MaybeObject* maybe_descriptors =
 | 
| -      DescriptorArray::Allocate(size, DescriptorArray::MAY_BE_SHARED);
 | 
| +  MaybeObject* maybe_descriptors = DescriptorArray::Allocate(size);
 | 
|    if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
 | 
|  
 | 
|    FixedArray::WhitenessWitness witness(new_descriptors);
 | 
| @@ -5260,26 +5256,28 @@ class TraversableMap : public Map {
 | 
|    // If we have an unvisited child map, return that one and advance. If we have
 | 
|    // none, return NULL and reset any destroyed FixedArray maps.
 | 
|    TraversableMap* ChildIteratorNext() {
 | 
| -    if (HasTransitionArray()) {
 | 
| -      TransitionArray* transition_array = unchecked_transition_array();
 | 
| -
 | 
| -      if (transition_array->HasPrototypeTransitions()) {
 | 
| -        HeapObject* proto_transitions =
 | 
| -            transition_array->UncheckedPrototypeTransitions();
 | 
| -        IntrusivePrototypeTransitionIterator proto_iterator(proto_transitions);
 | 
| -        if (proto_iterator.IsIterating()) {
 | 
| -          Map* next = proto_iterator.Next();
 | 
| -          if (next != NULL) return static_cast<TraversableMap*>(next);
 | 
| -        }
 | 
| -      }
 | 
| +    TransitionArray* transition_array = unchecked_transition_array();
 | 
| +    if (!transition_array->map()->IsSmi() &&
 | 
| +        !transition_array->IsTransitionArray()) {
 | 
| +      return NULL;
 | 
| +    }
 | 
|  
 | 
| -      IntrusiveMapTransitionIterator transition_iterator(transition_array);
 | 
| -      if (transition_iterator.IsIterating()) {
 | 
| -        Map* next = transition_iterator.Next();
 | 
| +    if (transition_array->HasPrototypeTransitions()) {
 | 
| +      HeapObject* proto_transitions =
 | 
| +          transition_array->UncheckedPrototypeTransitions();
 | 
| +      IntrusivePrototypeTransitionIterator proto_iterator(proto_transitions);
 | 
| +      if (proto_iterator.IsIterating()) {
 | 
| +        Map* next = proto_iterator.Next();
 | 
|          if (next != NULL) return static_cast<TraversableMap*>(next);
 | 
|        }
 | 
|      }
 | 
|  
 | 
| +    IntrusiveMapTransitionIterator transition_iterator(transition_array);
 | 
| +    if (transition_iterator.IsIterating()) {
 | 
| +      Map* next = transition_iterator.Next();
 | 
| +      if (next != NULL) return static_cast<TraversableMap*>(next);
 | 
| +    }
 | 
| +
 | 
|      return NULL;
 | 
|    }
 | 
|  };
 | 
| @@ -5829,21 +5827,17 @@ bool FixedArray::IsEqualTo(FixedArray* other) {
 | 
|  #endif
 | 
|  
 | 
|  
 | 
| -MaybeObject* DescriptorArray::Allocate(int number_of_descriptors,
 | 
| -                                       SharedMode shared_mode) {
 | 
| +MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) {
 | 
|    Heap* heap = Isolate::Current()->heap();
 | 
|    // Do not use DescriptorArray::cast on incomplete object.
 | 
|    FixedArray* result;
 | 
| -  if (number_of_descriptors == 0 && shared_mode == MAY_BE_SHARED) {
 | 
| -    return heap->empty_descriptor_array();
 | 
| -  }
 | 
| +  if (number_of_descriptors == 0) return heap->empty_descriptor_array();
 | 
|    // Allocate the array of keys.
 | 
|    MaybeObject* maybe_array =
 | 
|        heap->AllocateFixedArray(LengthFor(number_of_descriptors));
 | 
|    if (!maybe_array->To(&result)) return maybe_array;
 | 
|  
 | 
|    result->set(kEnumCacheIndex, Smi::FromInt(0));
 | 
| -  result->set(kTransitionsIndex, Smi::FromInt(0));
 | 
|    return result;
 | 
|  }
 | 
|  
 | 
| @@ -5880,25 +5874,6 @@ void DescriptorArray::CopyFrom(int dst_index,
 | 
|  }
 | 
|  
 | 
|  
 | 
| -MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) {
 | 
| -  // Allocate the new descriptor array.
 | 
| -  int number_of_descriptors = this->number_of_descriptors();
 | 
| -  DescriptorArray* new_descriptors;
 | 
| -  MaybeObject* maybe_result = Allocate(number_of_descriptors, shared_mode);
 | 
| -  if (!maybe_result->To(&new_descriptors)) return maybe_result;
 | 
| -
 | 
| -  // Copy the content.
 | 
| -  if (number_of_descriptors > 0) {
 | 
| -    FixedArray::WhitenessWitness witness(new_descriptors);
 | 
| -    for (int i = 0; i < number_of_descriptors; i++) {
 | 
| -      new_descriptors->CopyFrom(i, this, i, witness);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  return new_descriptors;
 | 
| -}
 | 
| -
 | 
| -
 | 
|  // We need the whiteness witness since sort will reshuffle the entries in the
 | 
|  // descriptor array. If the descriptor array were to be black, the shuffling
 | 
|  // would move a slot that was already recorded as pointing into an evacuation
 | 
| @@ -7251,7 +7226,8 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
 | 
|    // the transition array from the map.
 | 
|    if (transition_index == 0 &&
 | 
|        !t->HasElementsTransition() &&
 | 
| -      !t->HasPrototypeTransitions()) {
 | 
| +      !t->HasPrototypeTransitions() &&
 | 
| +      t->descriptors()->IsEmpty()) {
 | 
|      return ClearTransitions(heap);
 | 
|    }
 | 
|  
 | 
| @@ -7492,8 +7468,7 @@ MaybeObject* JSFunction::SetInstancePrototype(Object* value) {
 | 
|      // If the function has allocated the initial map
 | 
|      // replace it with a copy containing the new prototype.
 | 
|      Map* new_map;
 | 
| -    MaybeObject* maybe_new_map =
 | 
| -        initial_map()->Copy(DescriptorArray::MAY_BE_SHARED);
 | 
| +    MaybeObject* maybe_new_map = initial_map()->Copy();
 | 
|      if (!maybe_new_map->To(&new_map)) return maybe_new_map;
 | 
|      new_map->set_prototype(value);
 | 
|      MaybeObject* maybe_object = set_initial_map_and_cache_transitions(new_map);
 | 
| @@ -7522,7 +7497,7 @@ MaybeObject* JSFunction::SetPrototype(Object* value) {
 | 
|      // Remove map transitions because they point to maps with a
 | 
|      // different prototype.
 | 
|      Map* new_map;
 | 
| -    MaybeObject* maybe_new_map = map()->Copy(DescriptorArray::MAY_BE_SHARED);
 | 
| +    MaybeObject* maybe_new_map = map()->Copy();
 | 
|      if (!maybe_new_map->To(&new_map)) return maybe_new_map;
 | 
|  
 | 
|      Heap* heap = new_map->GetHeap();
 | 
| @@ -8816,7 +8791,7 @@ MaybeObject* JSReceiver::SetPrototype(Object* value,
 | 
|  
 | 
|    Map* new_map = map->GetPrototypeTransition(value);
 | 
|    if (new_map == NULL) {
 | 
| -    MaybeObject* maybe_new_map = map->Copy(DescriptorArray::MAY_BE_SHARED);
 | 
| +    MaybeObject* maybe_new_map = map->Copy();
 | 
|      if (!maybe_new_map->To(&new_map)) return maybe_new_map;
 | 
|  
 | 
|      MaybeObject* maybe_new_cache =
 | 
| @@ -12542,8 +12517,7 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
 | 
|    // Allocate the instance descriptor.
 | 
|    DescriptorArray* descriptors;
 | 
|    MaybeObject* maybe_descriptors =
 | 
| -      DescriptorArray::Allocate(instance_descriptor_length,
 | 
| -                                DescriptorArray::MAY_BE_SHARED);
 | 
| +      DescriptorArray::Allocate(instance_descriptor_length);
 | 
|    if (!maybe_descriptors->To(&descriptors)) {
 | 
|      return maybe_descriptors;
 | 
|    }
 | 
| @@ -12615,8 +12589,9 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
 | 
|  
 | 
|    descriptors->Sort(witness);
 | 
|  
 | 
| +  MaybeObject* maybe_failure = new_map->InitializeDescriptors(descriptors);
 | 
| +  if (maybe_failure->IsFailure()) return maybe_failure;
 | 
|    new_map->set_unused_property_fields(unused_property_fields);
 | 
| -  new_map->InitializeDescriptors(descriptors);
 | 
|  
 | 
|    // Transform the object.
 | 
|    obj->set_map(new_map);
 | 
| 
 |