| Index: src/objects.h | 
| diff --git a/src/objects.h b/src/objects.h | 
| index f547c8388cf9df637a2436ba64c4bd3342cbef7a..f110194ec87a23c30c8c2667b568501fb0a5214f 100644 | 
| --- a/src/objects.h | 
| +++ b/src/objects.h | 
| @@ -2468,17 +2468,6 @@ class FixedArray: public FixedArrayBase { | 
|  | 
| enum KeyFilter { ALL_KEYS, NON_SYMBOL_KEYS }; | 
|  | 
| -  // Add the elements of a JSArray to this FixedArray. | 
| -  MUST_USE_RESULT static MaybeHandle<FixedArray> AddKeysFromArrayLike( | 
| -      Handle<FixedArray> content, Handle<JSObject> array, | 
| -      KeyFilter filter = ALL_KEYS); | 
| - | 
| -  // Computes the union of keys and return the result. | 
| -  // Used for implementing "for (n in object) { }" | 
| -  MUST_USE_RESULT static MaybeHandle<FixedArray> UnionOfKeys( | 
| -      Handle<FixedArray> first, | 
| -      Handle<FixedArray> second); | 
| - | 
| // Copy a sub array from the receiver to dest. | 
| void CopyTo(int pos, FixedArray* dest, int dest_pos, int len); | 
|  | 
| @@ -3657,6 +3646,9 @@ class OrderedHashTable: public FixedArray { | 
| // exisiting iterators can be updated. | 
| static Handle<Derived> Clear(Handle<Derived> table); | 
|  | 
| +  // Returns a true if the OrderedHashTable contains the key | 
| +  static bool HasKey(Handle<Derived> table, Handle<Object> key); | 
| + | 
| int NumberOfElements() { | 
| return Smi::cast(get(kNumberOfElementsIndex))->value(); | 
| } | 
| @@ -3676,6 +3668,25 @@ class OrderedHashTable: public FixedArray { | 
| return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize); | 
| } | 
|  | 
| +  int HashToBucket(int hash) { return hash & (NumberOfBuckets() - 1); } | 
| + | 
| +  int HashToEntry(int hash) { | 
| +    int bucket = HashToBucket(hash); | 
| +    Object* entry = this->get(kHashTableStartIndex + bucket); | 
| +    return Smi::cast(entry)->value(); | 
| +  } | 
| + | 
| +  int KeyToFirstEntry(Object* key) { | 
| +    Object* hash = key->GetHash(); | 
| +    // If the object does not have an identity hash, it was never used as a key | 
| +    if (hash->IsUndefined()) return kNotFound; | 
| +    return HashToEntry(Smi::cast(hash)->value()); | 
| +  } | 
| + | 
| +  int NextChainEntry(int entry) { | 
| +    Object* next_entry = get(EntryToIndex(entry) + entrysize); | 
| +    return Smi::cast(next_entry)->value(); | 
| +  } | 
| Object* KeyAt(int entry) { return get(EntryToIndex(entry)); } | 
|  | 
| bool IsObsolete() { | 
| @@ -3722,7 +3733,7 @@ class OrderedHashTable: public FixedArray { | 
| // optimize that case. | 
| static const int kClearedTableSentinel = -1; | 
|  | 
| - private: | 
| + protected: | 
| static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity); | 
|  | 
| void SetNumberOfBuckets(int num) { | 
| @@ -3764,6 +3775,9 @@ class OrderedHashSet: public OrderedHashTable< | 
| OrderedHashSet, JSSetIterator, 1> { | 
| public: | 
| DECLARE_CAST(OrderedHashSet) | 
| + | 
| +  static Handle<OrderedHashSet> Add(Handle<OrderedHashSet> table, | 
| +                                    Handle<Object> value); | 
| }; | 
|  | 
|  | 
| @@ -10470,6 +10484,29 @@ class BooleanBit : public AllStatic { | 
| } | 
| }; | 
|  | 
| + | 
| +class KeyAccumulator final BASE_EMBEDDED { | 
| + public: | 
| +  explicit KeyAccumulator(Isolate* isolate) | 
| +      : isolate_(isolate), keys_(), set_(), length_(0) {} | 
| + | 
| +  void AddKey(Handle<Object> key, int check_limit); | 
| +  void AddKeys(Handle<FixedArray> array, FixedArray::KeyFilter filter); | 
| +  void AddKeys(Handle<JSObject> array, FixedArray::KeyFilter filter); | 
| +  void PrepareForComparisons(int count); | 
| +  int GetLength(); | 
| +  Handle<FixedArray> GetKeys(); | 
| + | 
| + private: | 
| +  void EnsureCapacity(int capacity); | 
| +  void Grow(); | 
| + | 
| +  Isolate* isolate_; | 
| +  Handle<FixedArray> keys_; | 
| +  Handle<OrderedHashSet> set_; | 
| +  int length_; | 
| +  DISALLOW_COPY_AND_ASSIGN(KeyAccumulator); | 
| +}; | 
| } }  // namespace v8::internal | 
|  | 
| #endif  // V8_OBJECTS_H_ | 
|  |