| Index: src/objects.h | 
| diff --git a/src/objects.h b/src/objects.h | 
| index 720d96e0ea22d891ee22f4668b2cd4a866dc8d91..44da3664e1536fff1e3c48947c50b899eccd7b74 100644 | 
| --- a/src/objects.h | 
| +++ b/src/objects.h | 
| @@ -177,6 +177,13 @@ enum TransitionFlag { | 
| OMIT_TRANSITION | 
| }; | 
|  | 
| +// Indicates whether we are only interested in the descriptors of a particular | 
| +// map, or in all descriptors in the descriptor array. | 
| +enum DescriptorFlag { | 
| +  ALL_DESCRIPTORS, | 
| +  OWN_DESCRIPTORS | 
| +}; | 
| + | 
|  | 
| // Instance size sentinel for objects of variable size. | 
| const int kVariableSizeSentinel = 0; | 
| @@ -2479,12 +2486,15 @@ class DescriptorArray: public FixedArray { | 
| } | 
|  | 
| inline int number_of_entries() { return number_of_descriptors(); } | 
| -  inline int NextEnumerationIndex() { return number_of_descriptors() + 1; } | 
|  | 
| bool HasEnumCache() { | 
| return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); | 
| } | 
|  | 
| +  void CopyEnumCacheFrom(DescriptorArray* array) { | 
| +    set(kEnumCacheIndex, array->get(kEnumCacheIndex)); | 
| +  } | 
| + | 
| Object* GetEnumCache() { | 
| ASSERT(HasEnumCache()); | 
| FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); | 
| @@ -2539,19 +2549,17 @@ class DescriptorArray: public FixedArray { | 
| int src_index, | 
| const WhitenessWitness&); | 
|  | 
| +  MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index); | 
| + | 
| // Sort the instance descriptors by the hash codes of their keys. | 
| void Sort(); | 
| -  inline void SwapSortedKeys(int first, int second); | 
|  | 
| // Search the instance descriptors for given name. | 
| -  INLINE(int Search(String* name)); | 
| +  INLINE(int Search(String* name, int number_of_own_descriptors)); | 
|  | 
| // As the above, but uses DescriptorLookupCache and updates it when | 
| // necessary. | 
| -  INLINE(int SearchWithCache(String* name)); | 
| - | 
| -  // Tells whether the name is present int the array. | 
| -  bool Contains(String* name) { return kNotFound != Search(name); } | 
| +  INLINE(int SearchWithCache(String* name, Map* map)); | 
|  | 
| // Allocates a DescriptorArray, but returns the singleton | 
| // empty descriptor array object if number_of_descriptors is 0. | 
| @@ -2594,7 +2602,7 @@ class DescriptorArray: public FixedArray { | 
|  | 
| #ifdef DEBUG | 
| // Is the descriptor array sorted and without duplicates? | 
| -  bool IsSortedNoDuplicates(); | 
| +  bool IsSortedNoDuplicates(int valid_descriptors = -1); | 
|  | 
| // Is the descriptor array consistent with the back pointers in targets? | 
| bool IsConsistentWithBackPointers(Map* current_map); | 
| @@ -2647,24 +2655,21 @@ class DescriptorArray: public FixedArray { | 
| kDescriptorValue; | 
| } | 
|  | 
| -  // Swap operation on FixedArray without using write barriers. | 
| -  static inline void NoIncrementalWriteBarrierSwap( | 
| -      FixedArray* array, int first, int second); | 
| - | 
| // Swap first and second descriptor. | 
| -  inline void NoIncrementalWriteBarrierSwapDescriptors( | 
| -      int first, int second); | 
| +  inline void SwapSortedKeys(int first, int second); | 
|  | 
| DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); | 
| }; | 
|  | 
|  | 
| -template<typename T> | 
| -inline int LinearSearch(T* array, String* name, int len); | 
| +enum SearchMode { ALL_ENTRIES, VALID_ENTRIES }; | 
|  | 
| +template<SearchMode search_mode, typename T> | 
| +inline int LinearSearch(T* array, String* name, int len, int valid_entries); | 
|  | 
| -template<typename T> | 
| -inline int Search(T* array, String* name); | 
| + | 
| +template<SearchMode search_mode, typename T> | 
| +inline int Search(T* array, String* name, int valid_entries = 0); | 
|  | 
|  | 
| // HashTable is a subclass of FixedArray that implements a hash table | 
| @@ -4670,6 +4675,7 @@ class Map: public HeapObject { | 
| class IsShared:                   public BitField<bool, 22,  1> {}; | 
| class FunctionWithPrototype:      public BitField<bool, 23,  1> {}; | 
| class DictionaryMap:              public BitField<bool, 24,  1> {}; | 
| +  class OwnsDescriptors:            public BitField<bool, 25,  1> {}; | 
|  | 
| // Tells whether the object in the prototype property will be used | 
| // for instances created from this function.  If the prototype | 
| @@ -4790,6 +4796,7 @@ class Map: public HeapObject { | 
| static bool IsValidElementsTransition(ElementsKind from_kind, | 
| ElementsKind to_kind); | 
|  | 
| +  bool StoresOwnDescriptors() { return HasTransitionArray(); } | 
| inline bool HasTransitionArray(); | 
| inline bool HasElementsTransition(); | 
| inline Map* elements_transition_map(); | 
| @@ -4836,8 +4843,7 @@ class Map: public HeapObject { | 
| // [instance descriptors]: describes the object. | 
| inline DescriptorArray* instance_descriptors(); | 
| MUST_USE_RESULT inline MaybeObject* SetDescriptors( | 
| -      DescriptorArray* descriptors, | 
| -      WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | 
| +      DescriptorArray* descriptors); | 
| static void SetDescriptors(Handle<Map> map, | 
| Handle<DescriptorArray> descriptors); | 
| MUST_USE_RESULT inline MaybeObject* InitializeDescriptors( | 
| @@ -4918,17 +4924,29 @@ class Map: public HeapObject { | 
| } | 
|  | 
| void SetNumberOfOwnDescriptors(int number) { | 
| +    ASSERT(number <= instance_descriptors()->number_of_descriptors()); | 
| set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number)); | 
| } | 
|  | 
| +  inline JSGlobalPropertyCell* RetrieveDescriptorsPointer(); | 
| + | 
| int EnumLength() { | 
| return EnumLengthBits::decode(bit_field3()); | 
| } | 
|  | 
| -  void SetEnumLength(int index) { | 
| -    set_bit_field3(EnumLengthBits::update(bit_field3(), index)); | 
| +  void SetEnumLength(int length) { | 
| +    if (length != kInvalidEnumCache) { | 
| +      ASSERT(length >= 0); | 
| +      ASSERT(length == 0 || instance_descriptors()->HasEnumCache()); | 
| +      ASSERT(length <= NumberOfOwnDescriptors()); | 
| +    } | 
| +    set_bit_field3(EnumLengthBits::update(bit_field3(), length)); | 
| } | 
|  | 
| + | 
| +  inline bool OwnsDescriptors(); | 
| +  inline void SetOwnsDescriptors(bool is_shared); | 
| + | 
| MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); | 
| MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors(); | 
| MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); | 
| @@ -4936,6 +4954,7 @@ class Map: public HeapObject { | 
| DescriptorArray* descriptors, | 
| String* name, | 
| TransitionFlag flag); | 
| +  MUST_USE_RESULT MaybeObject* ShareDescriptor(Descriptor* descriptor); | 
| MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor, | 
| TransitionFlag flag); | 
| MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor, | 
| @@ -4964,7 +4983,8 @@ class Map: public HeapObject { | 
|  | 
| // Returns the number of properties described in instance_descriptors | 
| // filtering out properties with the specified attributes. | 
| -  int NumberOfDescribedProperties(PropertyAttributes filter = NONE); | 
| +  int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS, | 
| +                                  PropertyAttributes filter = NONE); | 
|  | 
| // Casting. | 
| static inline Map* cast(Object* obj); | 
| @@ -5068,7 +5088,7 @@ class Map: public HeapObject { | 
|  | 
| static const int kMaxPreAllocatedPropertyFields = 255; | 
|  | 
| -  // Constant for denoting that the Enum Cache field was not yet used. | 
| +  // Constant for denoting that the enum cache is not yet initialized. | 
| static const int kInvalidEnumCache = EnumLengthBits::kMax; | 
|  | 
| // Layout description. | 
|  |