| Index: src/objects.h
|
| diff --git a/src/objects.h b/src/objects.h
|
| index 04cf5394d059d487191a924e4df7ee9795f26701..c2220860b779f7f9ae710adc273046f1e7aabf82 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;
|
| @@ -2481,12 +2488,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));
|
| @@ -2499,6 +2509,8 @@ class DescriptorArray: public FixedArray {
|
| kEnumCacheOffset);
|
| }
|
|
|
| + void ClearEnumCache();
|
| +
|
| // Initialize or change the enum cache,
|
| // using the supplied storage for the small "bridge".
|
| void SetEnumCache(FixedArray* bridge_storage,
|
| @@ -2541,19 +2553,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.
|
| @@ -2596,7 +2606,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);
|
| @@ -2649,24 +2659,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
|
| @@ -4672,6 +4679,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
|
| @@ -4792,12 +4800,14 @@ 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();
|
| MUST_USE_RESULT inline MaybeObject* set_elements_transition_map(
|
| Map* transitioned_map);
|
| - inline void SetTransition(int index, Map* target);
|
| + inline void SetTransition(int transition_index, Map* target);
|
| + inline Map* GetTransition(int transition_index);
|
| MUST_USE_RESULT inline MaybeObject* AddTransition(String* key, Map* target);
|
| DECL_ACCESSORS(transitions, TransitionArray)
|
| inline void ClearTransitions(Heap* heap,
|
| @@ -4837,9 +4847,9 @@ class Map: public HeapObject {
|
|
|
| // [instance descriptors]: describes the object.
|
| inline DescriptorArray* instance_descriptors();
|
| + inline JSGlobalPropertyCell* descriptors_pointer();
|
| 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(
|
| @@ -4920,17 +4930,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 owns_descriptors();
|
| + inline void set_owns_descriptors(bool is_shared);
|
| +
|
| MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
|
| MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors();
|
| MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
|
| @@ -4938,6 +4960,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,
|
| @@ -4966,7 +4989,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);
|
| @@ -5070,7 +5094,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.
|
|
|