OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef V8_MAP_RECONFIGURER_H_ | |
6 #define V8_MAP_RECONFIGURER_H_ | |
7 | |
8 #include "src/elements-kind.h" | |
9 #include "src/globals.h" | |
10 #include "src/handles.h" | |
11 #include "src/objects.h" | |
12 #include "src/property-details.h" | |
13 | |
14 namespace v8 { | |
15 namespace internal { | |
16 | |
17 // The |MapReconfigurer| class implements all sorts of map reconfigurations | |
18 // including changes of elements kind, property attributes, property kind, | |
19 // property location and field representations/type changes. It ensures that | |
20 // the reconfigured map and all the intermediate maps are propely integrated | |
Toon Verwaest
2017/01/09 13:01:19
properly
Igor Sheludko
2017/01/09 14:54:25
Done.
| |
21 // into the exising transition tree. | |
22 // | |
23 // To avoid high degrees over polymorphism, and to stabilize quickly, on every | |
24 // rewrite the new type is deduced by merging the current type with any | |
25 // potential new (partial) version of the type in the transition tree. | |
26 // To do this, on each rewrite: | |
27 // - Search the root of the transition tree using FindRootMap. | |
28 // - Find/create a |root_map| with requested |new_elements_kind|. | |
29 // - Find |target_map|, the newest matching version of this map using the | |
30 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at | |
Toon Verwaest
2017/01/09 13:01:19
"updated"
Igor Sheludko
2017/01/09 14:54:26
Done.
| |
31 // |modify_index| is considered to be of |new_kind| and having | |
32 // |new_attributes|) to walk the transition tree. | |
33 // - Merge/generalize the "enhanced" descriptor array of the |old_map| and | |
Toon Verwaest
2017/01/09 13:01:19
"updated"
Igor Sheludko
2017/01/09 14:54:25
Done.
| |
34 // descriptor array of the |target_map|. | |
35 // - Generalize the |modify_index| descriptor using |new_representation| and | |
36 // |new_field_type|. | |
37 // - Walk the tree again starting from the root towards |target_map|. Stop at | |
38 // |split_map|, the first map who's descriptor array does not match the merged | |
39 // descriptor array. | |
40 // - If |target_map| == |split_map|, |target_map| is in the expected state. | |
41 // Return it. | |
42 // - Otherwise, invalidate the outdated transition target from |target_map|, and | |
43 // replace its transition tree with a new branch for the updated descriptors. | |
44 class MapReconfigurer { | |
45 public: | |
46 MapReconfigurer(Isolate* isolate, Handle<Map> old_map) | |
47 : isolate_(isolate), | |
48 old_map_(old_map), | |
49 old_descriptors_(old_map->instance_descriptors(), isolate_), | |
50 old_nof_(old_map_->NumberOfOwnDescriptors()), | |
51 new_elements_kind_(old_map_->elements_kind()) {} | |
52 | |
53 // Prepares for reconfiguring of a property at |descriptor| to data field | |
54 // with given |attributes| and |representation|/|field_type| and | |
55 // performs the steps 1-5. | |
56 Handle<Map> ReconfigureToDataField(int descriptor, | |
57 PropertyAttributes attributes, | |
58 Representation representation, | |
59 Handle<FieldType> field_type); | |
60 | |
61 // Prepares for reconfiguring elements kind and performs the steps 1-5. | |
62 Handle<Map> ReconfigureElementsKind(ElementsKind elements_kind); | |
63 | |
64 // Prepares for updating deprecated map to most up-to-date non-deprecated | |
65 // version and performs the steps 1-5. | |
66 Handle<Map> Update(); | |
67 | |
68 private: | |
69 enum State { kInitialized, kAtRootMap, kAtTargetMap, kEnd }; | |
70 | |
71 // Try to reconfigure property in-place without rebuilding transition tree | |
72 // and creating new maps. See implementation for details. | |
73 bool TryRecofigureToDataFieldInplace(); | |
74 | |
75 // Step 1. | |
76 // - Search the root of the transition tree using FindRootMap. | |
77 // - Find/create a |root_map_| with requested |new_elements_kind_|. | |
78 bool FindRootMap(); | |
79 | |
80 // Step 2. | |
81 // - Find |target_map_|, the newest matching version of this map using the | |
82 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at | |
83 // |modified_descriptor_| is considered to be of |new_kind| and having | |
84 // |new_attributes|) to walk the transition tree. | |
85 bool FindTargetMap(); | |
86 | |
87 // Step 3. | |
88 // - Merge/generalize the "enhanced" descriptor array of the |old_map_| and | |
89 // descriptor array of the |target_map_|. | |
90 // - Generalize the |modified_descriptor_| using |new_representation| and | |
91 // |new_field_type_|. | |
92 Handle<DescriptorArray> BuildDescriptorArray(); | |
93 | |
94 // Step 4. | |
95 // - Walk the tree again starting from the root towards |target_map|. Stop at | |
96 // |split_map|, the first map who's descriptor array does not match the | |
97 // merged descriptor array. | |
98 Handle<Map> FindSplitMap(Handle<DescriptorArray> descriptors); | |
99 | |
100 // Step 5. | |
101 // - If |target_map| == |split_map|, |target_map| is in the expected state. | |
102 // Return it. | |
103 // - Otherwise, invalidate the outdated transition target from |target_map|, | |
104 // and replace its transition tree with a new branch for the updated | |
105 // descriptors. | |
106 bool ConstructNewMap(); | |
107 | |
108 // When a requested reconfiguration can not be done the result is a copy | |
109 // of |old_map_| where every field has |Tagged| representation and |Any| | |
110 // field type. This map is disconnected from the transition tree. | |
111 bool CopyGeneralizeAllRepresentations(const char* reason); | |
112 | |
113 // Helper method, returns the resulting map. | |
114 inline Handle<Map> Result() const; | |
115 | |
116 // Returns name of a |descriptor| property. | |
117 inline Name* GetKey(int descriptor) const; | |
118 | |
119 // Returns property details of a |descriptor| in virtually "enhanced" | |
120 // |old_descrtiptors_| array. | |
121 inline PropertyDetails GetDetails(int descriptor) const; | |
122 | |
123 // Returns value of a |descriptor| with kDescriptor location in virtually | |
124 // "enhanced" |old_descrtiptors_| array. | |
125 inline Object* GetValue(int descriptor) const; | |
126 | |
127 // Returns field type for a |descriptor| with kField location in virtually | |
128 // "enhanced" |old_descrtiptors_| array. | |
129 inline FieldType* GetFieldType(int descriptor) const; | |
130 | |
131 // If a |descriptor| property in virtually "enhanced" |old_descriptors_| | |
132 // has kField location then returns it's field type otherwise computes | |
133 // optimal field type for the descriptor's value and |representation|. | |
134 // The |location| value must be a pre-fetched location for |descriptor|. | |
135 inline Handle<FieldType> GetOrComputeFieldType( | |
136 int descriptor, PropertyLocation location, | |
137 Representation representation) const; | |
138 | |
139 // If a |descriptor| property in given |descriptors| array has kField | |
140 // location then returns it's field type otherwise computes optimal field | |
141 // type for the descriptor's value and |representation|. | |
142 // The |location| value must be a pre-fetched location for |descriptor|. | |
143 inline Handle<FieldType> GetOrComputeFieldType( | |
144 Handle<DescriptorArray> descriptors, int descriptor, | |
145 PropertyLocation location, Representation representation); | |
146 | |
147 Isolate* isolate_; | |
148 Handle<Map> old_map_; | |
149 Handle<DescriptorArray> old_descriptors_; | |
150 Handle<Map> root_map_; | |
151 Handle<Map> target_map_; | |
152 Handle<Map> result_map_; | |
153 int old_nof_; | |
154 | |
155 State state_ = kInitialized; | |
156 ElementsKind new_elements_kind_; | |
157 | |
158 // If |modified_descriptor_| is not equal to -1 them the fields below form | |
159 // an "enhancement" of the |old_map_|'s descriptors. | |
160 int modified_descriptor_ = -1; | |
161 PropertyKind new_kind_ = kData; | |
162 PropertyAttributes new_attributes_ = NONE; | |
163 PropertyLocation new_location_ = kField; | |
164 Representation new_representation_ = Representation::None(); | |
165 | |
166 // Data specific to kField location. | |
167 Handle<FieldType> new_field_type_; | |
168 | |
169 // Data specific to kDescriptor location. | |
170 Handle<Object> new_value_; | |
171 }; | |
172 | |
173 } // namespace internal | |
174 } // namespace v8 | |
175 | |
176 #endif // V8_MAP_RECONFIGURER_H_ | |
OLD | NEW |