| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_TRANSITIONS_H_ | 5 #ifndef V8_TRANSITIONS_H_ |
| 6 #define V8_TRANSITIONS_H_ | 6 #define V8_TRANSITIONS_H_ |
| 7 | 7 |
| 8 #include "src/checks.h" | 8 #include "src/checks.h" |
| 9 #include "src/elements-kind.h" | 9 #include "src/elements-kind.h" |
| 10 #include "src/heap/heap.h" | 10 #include "src/heap/heap.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 // map. In the case of a simple transition, the key is also read from the | 23 // map. In the case of a simple transition, the key is also read from the |
| 24 // descriptor array of the target map. | 24 // descriptor array of the target map. |
| 25 // | 25 // |
| 26 // The simple format of the these objects is: | 26 // The simple format of the these objects is: |
| 27 // [0] Undefined or back pointer map | 27 // [0] Undefined or back pointer map |
| 28 // [1] Single transition | 28 // [1] Single transition |
| 29 // | 29 // |
| 30 // The full format is: | 30 // The full format is: |
| 31 // [0] Undefined or back pointer map | 31 // [0] Undefined or back pointer map |
| 32 // [1] Smi(0) or fixed array of prototype transitions | 32 // [1] Smi(0) or fixed array of prototype transitions |
| 33 // [2] First transition | 33 // [2] Number of transitions |
| 34 // [length() - kTransitionSize] Last transition | 34 // [3] First transition |
| 35 // [3 + number of transitions * kTransitionSize]: start of slack |
| 35 class TransitionArray: public FixedArray { | 36 class TransitionArray: public FixedArray { |
| 36 public: | 37 public: |
| 37 // Accessors for fetching instance transition at transition number. | 38 // Accessors for fetching instance transition at transition number. |
| 38 inline Name* GetKey(int transition_number); | 39 inline Name* GetKey(int transition_number); |
| 39 inline void SetKey(int transition_number, Name* value); | 40 inline void SetKey(int transition_number, Name* value); |
| 40 inline Object** GetKeySlot(int transition_number); | 41 inline Object** GetKeySlot(int transition_number); |
| 41 int GetSortedKeyIndex(int transition_number) { return transition_number; } | 42 int GetSortedKeyIndex(int transition_number) { return transition_number; } |
| 42 | 43 |
| 43 Name* GetSortedKey(int transition_number) { | 44 Name* GetSortedKey(int transition_number) { |
| 44 return GetKey(transition_number); | 45 return GetKey(transition_number); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 60 inline FixedArray* GetPrototypeTransitions(); | 61 inline FixedArray* GetPrototypeTransitions(); |
| 61 inline void SetPrototypeTransitions( | 62 inline void SetPrototypeTransitions( |
| 62 FixedArray* prototype_transitions, | 63 FixedArray* prototype_transitions, |
| 63 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | 64 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
| 64 inline Object** GetPrototypeTransitionsSlot(); | 65 inline Object** GetPrototypeTransitionsSlot(); |
| 65 inline bool HasPrototypeTransitions(); | 66 inline bool HasPrototypeTransitions(); |
| 66 | 67 |
| 67 // Returns the number of transitions in the array. | 68 // Returns the number of transitions in the array. |
| 68 int number_of_transitions() { | 69 int number_of_transitions() { |
| 69 if (IsSimpleTransition()) return 1; | 70 if (IsSimpleTransition()) return 1; |
| 70 int len = length(); | 71 if (length() <= kFirstIndex) return 0; |
| 71 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kTransitionSize; | 72 return Smi::cast(get(kTransitionLengthIndex))->value(); |
| 72 } | 73 } |
| 73 | 74 |
| 75 int number_of_transitions_storage() { |
| 76 if (IsSimpleTransition()) return 1; |
| 77 if (length() <= kFirstIndex) return 0; |
| 78 return (length() - kFirstIndex) / kTransitionSize; |
| 79 } |
| 80 |
| 81 int NumberOfSlackTransitions() { |
| 82 return number_of_transitions_storage() - number_of_transitions(); |
| 83 } |
| 84 |
| 85 inline void SetNumberOfTransitions(int number_of_transitions); |
| 74 inline int number_of_entries() { return number_of_transitions(); } | 86 inline int number_of_entries() { return number_of_transitions(); } |
| 75 | 87 |
| 76 // Creates a FullTransitionArray from a SimpleTransitionArray in | 88 // Creates a FullTransitionArray from a SimpleTransitionArray in |
| 77 // containing_map. | 89 // containing_map. |
| 78 static Handle<TransitionArray> ExtendToFullTransitionArray( | 90 static Handle<TransitionArray> ExtendToFullTransitionArray( |
| 79 Handle<Map> containing_map); | 91 Handle<Map> containing_map); |
| 80 | 92 |
| 81 // Create a transition array, copying from the owning map if it already has | 93 // Return a transition array, using the array from the owning map if it |
| 82 // one, otherwise creating a new one according to flag. | 94 // already has one (copying into a larger array if necessary), otherwise |
| 95 // creating a new one according to flag. |
| 83 // TODO(verwaest): This should not cause an existing transition to be | 96 // TODO(verwaest): This should not cause an existing transition to be |
| 84 // overwritten. | 97 // overwritten. |
| 85 static Handle<TransitionArray> CopyInsert(Handle<Map> map, | 98 static Handle<TransitionArray> Insert(Handle<Map> map, Handle<Name> name, |
| 86 Handle<Name> name, | 99 Handle<Map> target, |
| 87 Handle<Map> target, | 100 SimpleTransitionFlag flag); |
| 88 SimpleTransitionFlag flag); | |
| 89 | 101 |
| 90 // Search a transition for a given property name. | 102 // Search a transition for a given property name. |
| 91 inline int Search(Name* name); | 103 inline int Search(Name* name); |
| 92 | 104 |
| 93 // Allocates a TransitionArray. | 105 // Allocates a TransitionArray. |
| 94 static Handle<TransitionArray> Allocate( | 106 static Handle<TransitionArray> Allocate(Isolate* isolate, |
| 95 Isolate* isolate, int number_of_transitions); | 107 int number_of_transitions, |
| 108 int slack = 0); |
| 96 | 109 |
| 97 bool IsSimpleTransition() { | 110 bool IsSimpleTransition() { |
| 98 return length() == kSimpleTransitionSize && | 111 return length() == kSimpleTransitionSize && |
| 99 get(kSimpleTransitionTarget)->IsHeapObject() && | 112 get(kSimpleTransitionTarget)->IsHeapObject() && |
| 100 // The IntrusivePrototypeTransitionIterator may have set the map of the | 113 // The IntrusivePrototypeTransitionIterator may have set the map of the |
| 101 // prototype transitions array to a smi. In that case, there are | 114 // prototype transitions array to a smi. In that case, there are |
| 102 // prototype transitions, hence this transition array is a full | 115 // prototype transitions, hence this transition array is a full |
| 103 // transition array. | 116 // transition array. |
| 104 HeapObject::cast(get(kSimpleTransitionTarget))->map()->IsMap() && | 117 HeapObject::cast(get(kSimpleTransitionTarget))->map()->IsMap() && |
| 105 get(kSimpleTransitionTarget)->IsMap(); | 118 get(kSimpleTransitionTarget)->IsMap(); |
| 106 } | 119 } |
| 107 | 120 |
| 108 bool IsFullTransitionArray() { | 121 bool IsFullTransitionArray() { |
| 109 return length() > kFirstIndex || | 122 return length() > kFirstIndex || |
| 110 (length() == kFirstIndex && !IsSimpleTransition()); | 123 (length() == kFirstIndex && !IsSimpleTransition()); |
| 111 } | 124 } |
| 112 | 125 |
| 113 // Casting. | 126 // Casting. |
| 114 static inline TransitionArray* cast(Object* obj); | 127 static inline TransitionArray* cast(Object* obj); |
| 115 | 128 |
| 116 // Constant for denoting key was not found. | 129 // Constant for denoting key was not found. |
| 117 static const int kNotFound = -1; | 130 static const int kNotFound = -1; |
| 118 | 131 |
| 119 static const int kBackPointerStorageIndex = 0; | 132 static const int kBackPointerStorageIndex = 0; |
| 120 | 133 |
| 121 // Layout for full transition arrays. | 134 // Layout for full transition arrays. |
| 122 static const int kPrototypeTransitionsIndex = 1; | 135 static const int kPrototypeTransitionsIndex = 1; |
| 123 static const int kFirstIndex = 2; | 136 static const int kTransitionLengthIndex = 2; |
| 137 static const int kFirstIndex = 3; |
| 124 | 138 |
| 125 // Layout for simple transition arrays. | 139 // Layout for simple transition arrays. |
| 126 static const int kSimpleTransitionTarget = 1; | 140 static const int kSimpleTransitionTarget = 1; |
| 127 static const int kSimpleTransitionSize = 2; | 141 static const int kSimpleTransitionSize = 2; |
| 128 static const int kSimpleTransitionIndex = 0; | 142 static const int kSimpleTransitionIndex = 0; |
| 129 STATIC_ASSERT(kSimpleTransitionIndex != kNotFound); | 143 STATIC_ASSERT(kSimpleTransitionIndex != kNotFound); |
| 130 | 144 |
| 131 static const int kBackPointerStorageOffset = FixedArray::kHeaderSize; | 145 static const int kBackPointerStorageOffset = FixedArray::kHeaderSize; |
| 132 | 146 |
| 133 // Layout for the full transition array header. | 147 // Layout for the full transition array header. |
| 134 static const int kPrototypeTransitionsOffset = kBackPointerStorageOffset + | 148 static const int kPrototypeTransitionsOffset = kBackPointerStorageOffset + |
| 135 kPointerSize; | 149 kPointerSize; |
| 150 static const int kTransitionLengthOffset = |
| 151 kPrototypeTransitionsOffset + kPointerSize; |
| 136 | 152 |
| 137 // Layout of map transition entries in full transition arrays. | 153 // Layout of map transition entries in full transition arrays. |
| 138 static const int kTransitionKey = 0; | 154 static const int kTransitionKey = 0; |
| 139 static const int kTransitionTarget = 1; | 155 static const int kTransitionTarget = 1; |
| 140 static const int kTransitionSize = 2; | 156 static const int kTransitionSize = 2; |
| 141 | 157 |
| 142 #ifdef OBJECT_PRINT | 158 #ifdef OBJECT_PRINT |
| 143 // For our gdb macros, we should perhaps change these in the future. | 159 // For our gdb macros, we should perhaps change these in the future. |
| 144 void Print(); | 160 void Print(); |
| 145 | 161 |
| 146 // Print all the transitions. | 162 // Print all the transitions. |
| 147 void PrintTransitions(std::ostream& os, bool print_header = true); // NOLINT | 163 void PrintTransitions(std::ostream& os, bool print_header = true); // NOLINT |
| 148 #endif | 164 #endif |
| 149 | 165 |
| 150 #ifdef DEBUG | 166 #ifdef DEBUG |
| 151 bool IsSortedNoDuplicates(int valid_entries = -1); | 167 bool IsSortedNoDuplicates(int valid_entries = -1); |
| 152 bool IsConsistentWithBackPointers(Map* current_map); | 168 bool IsConsistentWithBackPointers(Map* current_map); |
| 153 bool IsEqualTo(TransitionArray* other); | 169 bool IsEqualTo(TransitionArray* other); |
| 154 #endif | 170 #endif |
| 155 | 171 |
| 156 // The maximum number of transitions we want in a transition array (should | 172 // The maximum number of transitions we want in a transition array (should |
| 157 // fit in a page). | 173 // fit in a page). |
| 158 static const int kMaxNumberOfTransitions = 1024 + 512; | 174 static const int kMaxNumberOfTransitions = 1024 + 512; |
| 159 | 175 |
| 176 // Returns the fixed array length required to hold number_of_transitions |
| 177 // transitions. |
| 178 static int LengthFor(int number_of_transitions) { |
| 179 return ToKeyIndex(number_of_transitions); |
| 180 } |
| 181 |
| 160 private: | 182 private: |
| 161 // Conversion from transition number to array indices. | 183 // Conversion from transition number to array indices. |
| 162 static int ToKeyIndex(int transition_number) { | 184 static int ToKeyIndex(int transition_number) { |
| 163 return kFirstIndex + | 185 return kFirstIndex + |
| 164 (transition_number * kTransitionSize) + | 186 (transition_number * kTransitionSize) + |
| 165 kTransitionKey; | 187 kTransitionKey; |
| 166 } | 188 } |
| 167 | 189 |
| 168 static int ToTargetIndex(int transition_number) { | 190 static int ToTargetIndex(int transition_number) { |
| 169 return kFirstIndex + | 191 return kFirstIndex + |
| (...skipping 19 matching lines...) Expand all Loading... |
| 189 int origin_transition, | 211 int origin_transition, |
| 190 int target_transition); | 212 int target_transition); |
| 191 | 213 |
| 192 DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray); | 214 DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray); |
| 193 }; | 215 }; |
| 194 | 216 |
| 195 | 217 |
| 196 } } // namespace v8::internal | 218 } } // namespace v8::internal |
| 197 | 219 |
| 198 #endif // V8_TRANSITIONS_H_ | 220 #endif // V8_TRANSITIONS_H_ |
| OLD | NEW |