OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_LOOKUP_H_ | 5 #ifndef V8_LOOKUP_H_ |
6 #define V8_LOOKUP_H_ | 6 #define V8_LOOKUP_H_ |
7 | 7 |
8 #include "src/factory.h" | 8 #include "src/factory.h" |
9 #include "src/isolate.h" | 9 #include "src/isolate.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 CHECK_DERIVED = CHECK_DERIVED_SKIP_INTERCEPTOR | CHECK_INTERCEPTOR, | 30 CHECK_DERIVED = CHECK_DERIVED_SKIP_INTERCEPTOR | CHECK_INTERCEPTOR, |
31 CHECK_HIDDEN = CHECK_HIDDEN_SKIP_INTERCEPTOR | CHECK_INTERCEPTOR | 31 CHECK_HIDDEN = CHECK_HIDDEN_SKIP_INTERCEPTOR | CHECK_INTERCEPTOR |
32 }; | 32 }; |
33 | 33 |
34 enum State { | 34 enum State { |
35 ACCESS_CHECK, | 35 ACCESS_CHECK, |
36 INTERCEPTOR, | 36 INTERCEPTOR, |
37 JSPROXY, | 37 JSPROXY, |
38 NOT_FOUND, | 38 NOT_FOUND, |
39 PROPERTY, | 39 PROPERTY, |
| 40 TRANSITION, |
40 // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a | 41 // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a |
41 // PROPERTY lookup. | 42 // PROPERTY lookup. |
42 BEFORE_PROPERTY = INTERCEPTOR | 43 BEFORE_PROPERTY = INTERCEPTOR |
43 }; | 44 }; |
44 | 45 |
45 enum PropertyKind { | 46 enum PropertyKind { |
46 DATA, | 47 DATA, |
47 ACCESSOR | 48 ACCESSOR |
48 }; | 49 }; |
49 | 50 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 void NotFound() { | 108 void NotFound() { |
108 has_property_ = false; | 109 has_property_ = false; |
109 state_ = NOT_FOUND; | 110 state_ = NOT_FOUND; |
110 } | 111 } |
111 | 112 |
112 Heap* heap() const { return isolate_->heap(); } | 113 Heap* heap() const { return isolate_->heap(); } |
113 Factory* factory() const { return isolate_->factory(); } | 114 Factory* factory() const { return isolate_->factory(); } |
114 Handle<Object> GetReceiver() const { | 115 Handle<Object> GetReceiver() const { |
115 return maybe_receiver_.ToHandleChecked(); | 116 return maybe_receiver_.ToHandleChecked(); |
116 } | 117 } |
| 118 Handle<JSObject> GetStoreTarget() const; |
117 Handle<Map> holder_map() const { return holder_map_; } | 119 Handle<Map> holder_map() const { return holder_map_; } |
| 120 Handle<Map> transition_map() const { |
| 121 DCHECK_EQ(TRANSITION, state_); |
| 122 return transition_map_; |
| 123 } |
118 template <class T> | 124 template <class T> |
119 Handle<T> GetHolder() const { | 125 Handle<T> GetHolder() const { |
120 DCHECK(IsFound()); | 126 DCHECK(IsFound()); |
121 return Handle<T>::cast(maybe_holder_.ToHandleChecked()); | 127 return Handle<T>::cast(maybe_holder_.ToHandleChecked()); |
122 } | 128 } |
123 Handle<JSReceiver> GetRoot() const; | 129 Handle<JSReceiver> GetRoot() const; |
124 bool HolderIsReceiverOrHiddenPrototype() const; | 130 bool HolderIsReceiverOrHiddenPrototype() const; |
125 bool HolderIsNonGlobalHiddenPrototype() const; | 131 bool HolderIsNonGlobalHiddenPrototype() const; |
126 | 132 |
127 /* ACCESS_CHECK */ | 133 /* ACCESS_CHECK */ |
128 bool HasAccess(v8::AccessType access_type) const; | 134 bool HasAccess(v8::AccessType access_type) const; |
129 | 135 |
130 /* PROPERTY */ | 136 /* PROPERTY */ |
131 // HasProperty needs to be called before any of the other PROPERTY methods | 137 // HasProperty needs to be called before any of the other PROPERTY methods |
132 // below can be used. It ensures that we are able to provide a definite | 138 // below can be used. It ensures that we are able to provide a definite |
133 // answer, and loads extra information about the property. | 139 // answer, and loads extra information about the property. |
134 bool HasProperty(); | 140 bool HasProperty(); |
135 void PrepareForDataProperty(Handle<Object> value); | 141 void PrepareForDataProperty(Handle<Object> value); |
136 void TransitionToDataProperty(Handle<Object> value, | 142 void PrepareTransitionToDataProperty(Handle<Object> value, |
137 PropertyAttributes attributes, | 143 PropertyAttributes attributes, |
138 Object::StoreFromKeyed store_mode); | 144 Object::StoreFromKeyed store_mode); |
| 145 bool IsCacheableTransition() { |
| 146 bool cacheable = |
| 147 state_ == TRANSITION && transition_map()->GetBackPointer()->IsMap(); |
| 148 if (cacheable) { |
| 149 property_details_ = transition_map_->GetLastDescriptorDetails(); |
| 150 LoadPropertyKind(); |
| 151 has_property_ = true; |
| 152 } |
| 153 return cacheable; |
| 154 } |
| 155 void ApplyTransitionToDataProperty(); |
139 void ReconfigureDataProperty(Handle<Object> value, | 156 void ReconfigureDataProperty(Handle<Object> value, |
140 PropertyAttributes attributes); | 157 PropertyAttributes attributes); |
141 void TransitionToAccessorProperty(AccessorComponent component, | 158 void TransitionToAccessorProperty(AccessorComponent component, |
142 Handle<Object> accessor, | 159 Handle<Object> accessor, |
143 PropertyAttributes attributes); | 160 PropertyAttributes attributes); |
144 PropertyKind property_kind() const { | 161 PropertyKind property_kind() const { |
145 DCHECK(has_property_); | 162 DCHECK(has_property_); |
146 return property_kind_; | 163 return property_kind_; |
147 } | 164 } |
148 PropertyEncoding property_encoding() const { | 165 PropertyEncoding property_encoding() const { |
149 DCHECK(has_property_); | 166 DCHECK(has_property_); |
150 return property_encoding_; | 167 return property_encoding_; |
151 } | 168 } |
152 PropertyDetails property_details() const { | 169 PropertyDetails property_details() const { |
153 DCHECK(has_property_); | 170 DCHECK(has_property_); |
154 return property_details_; | 171 return property_details_; |
155 } | 172 } |
156 bool IsConfigurable() const { return property_details().IsConfigurable(); } | 173 bool IsConfigurable() const { return property_details().IsConfigurable(); } |
157 bool IsReadOnly() const { return property_details().IsReadOnly(); } | 174 bool IsReadOnly() const { return property_details().IsReadOnly(); } |
158 Representation representation() const { | 175 Representation representation() const { |
159 return property_details().representation(); | 176 return property_details().representation(); |
160 } | 177 } |
161 FieldIndex GetFieldIndex() const; | 178 FieldIndex GetFieldIndex() const; |
| 179 Handle<HeapType> GetFieldType() const; |
162 int GetConstantIndex() const; | 180 int GetConstantIndex() const; |
163 Handle<PropertyCell> GetPropertyCell() const; | 181 Handle<PropertyCell> GetPropertyCell() const; |
164 Handle<Object> GetAccessors() const; | 182 Handle<Object> GetAccessors() const; |
165 Handle<Object> GetDataValue() const; | 183 Handle<Object> GetDataValue() const; |
166 void WriteDataValue(Handle<Object> value); | 184 void WriteDataValue(Handle<Object> value); |
167 | 185 |
168 void InternalizeName(); | 186 void InternalizeName(); |
169 | 187 |
170 private: | 188 private: |
171 Handle<Map> GetReceiverMap() const; | 189 Handle<Map> GetReceiverMap() const; |
172 | 190 |
173 MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map); | 191 MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map); |
174 inline State LookupInHolder(Map* map); | 192 inline State LookupInHolder(Map* map); |
175 Handle<Object> FetchValue() const; | 193 Handle<Object> FetchValue() const; |
176 void ReloadPropertyInformation(); | 194 void ReloadPropertyInformation(); |
| 195 void LoadPropertyKind(); |
177 | 196 |
178 bool IsBootstrapping() const; | 197 bool IsBootstrapping() const; |
179 | 198 |
180 // Methods that fetch data from the holder ensure they always have a holder. | 199 // Methods that fetch data from the holder ensure they always have a holder. |
181 // This means the receiver needs to be present as opposed to just the receiver | 200 // This means the receiver needs to be present as opposed to just the receiver |
182 // map. Other objects in the prototype chain are transitively guaranteed to be | 201 // map. Other objects in the prototype chain are transitively guaranteed to be |
183 // present via the receiver map. | 202 // present via the receiver map. |
184 bool is_guaranteed_to_have_holder() const { | 203 bool is_guaranteed_to_have_holder() const { |
185 return !maybe_receiver_.is_null(); | 204 return !maybe_receiver_.is_null(); |
186 } | 205 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 // HolderIsReceiverOrHiddenPrototype. | 239 // HolderIsReceiverOrHiddenPrototype. |
221 Configuration configuration_; | 240 Configuration configuration_; |
222 State state_; | 241 State state_; |
223 bool has_property_; | 242 bool has_property_; |
224 PropertyKind property_kind_; | 243 PropertyKind property_kind_; |
225 PropertyEncoding property_encoding_; | 244 PropertyEncoding property_encoding_; |
226 PropertyDetails property_details_; | 245 PropertyDetails property_details_; |
227 Isolate* isolate_; | 246 Isolate* isolate_; |
228 Handle<Name> name_; | 247 Handle<Name> name_; |
229 Handle<Map> holder_map_; | 248 Handle<Map> holder_map_; |
| 249 Handle<Map> transition_map_; |
230 MaybeHandle<Object> maybe_receiver_; | 250 MaybeHandle<Object> maybe_receiver_; |
231 MaybeHandle<JSReceiver> maybe_holder_; | 251 MaybeHandle<JSReceiver> maybe_holder_; |
232 | 252 |
233 int number_; | 253 int number_; |
234 }; | 254 }; |
235 | 255 |
236 | 256 |
237 } } // namespace v8::internal | 257 } } // namespace v8::internal |
238 | 258 |
239 #endif // V8_LOOKUP_H_ | 259 #endif // V8_LOOKUP_H_ |
OLD | NEW |