Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: src/compiler/property-access-info.cc

Issue 1427913003: [turbofan] Add support for loading missing properties. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/property-access-info.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 #include <ostream> 5 #include <ostream>
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/compilation-dependencies.h" 8 #include "src/compilation-dependencies.h"
9 #include "src/compiler/property-access-info.h" 9 #include "src/compiler/property-access-info.h"
10 #include "src/field-index-inl.h" 10 #include "src/field-index-inl.h"
(...skipping 10 matching lines...) Expand all
21 case PropertyAccessMode::kLoad: 21 case PropertyAccessMode::kLoad:
22 return os << "Load"; 22 return os << "Load";
23 case PropertyAccessMode::kStore: 23 case PropertyAccessMode::kStore:
24 return os << "Store"; 24 return os << "Store";
25 } 25 }
26 UNREACHABLE(); 26 UNREACHABLE();
27 return os; 27 return os;
28 } 28 }
29 29
30 30
31 // static
32 PropertyAccessInfo PropertyAccessInfo::NotFound(Type* receiver_type,
33 MaybeHandle<JSObject> holder) {
34 return PropertyAccessInfo(holder, receiver_type);
35 }
36
37
38 // static
39 PropertyAccessInfo PropertyAccessInfo::DataConstant(
40 Type* receiver_type, Handle<Object> constant,
41 MaybeHandle<JSObject> holder) {
42 return PropertyAccessInfo(holder, constant, receiver_type);
43 }
44
45
46 // static
47 PropertyAccessInfo PropertyAccessInfo::DataField(
48 Type* receiver_type, FieldIndex field_index, Type* field_type,
49 MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map) {
50 return PropertyAccessInfo(holder, transition_map, field_index, field_type,
51 receiver_type);
52 }
53
54
31 PropertyAccessInfo::PropertyAccessInfo() 55 PropertyAccessInfo::PropertyAccessInfo()
32 : kind_(kInvalid), receiver_type_(Type::None()), field_type_(Type::Any()) {} 56 : kind_(kInvalid), receiver_type_(Type::None()), field_type_(Type::Any()) {}
33 57
34 58
35 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, 59 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
60 Type* receiver_type)
61 : kind_(kNotFound),
62 receiver_type_(receiver_type),
63 holder_(holder),
64 field_type_(Type::Any()) {}
65
66
67 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
36 Handle<Object> constant, 68 Handle<Object> constant,
37 Type* receiver_type) 69 Type* receiver_type)
38 : kind_(kDataConstant), 70 : kind_(kDataConstant),
39 receiver_type_(receiver_type), 71 receiver_type_(receiver_type),
40 constant_(constant), 72 constant_(constant),
41 holder_(holder), 73 holder_(holder),
42 field_type_(Type::Any()) {} 74 field_type_(Type::Any()) {}
43 75
44 76
45 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, 77 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // Compute the receiver type. 120 // Compute the receiver type.
89 Handle<Map> receiver_map = map; 121 Handle<Map> receiver_map = map;
90 122
91 // We support fast inline cases for certain JSObject getters. 123 // We support fast inline cases for certain JSObject getters.
92 if (access_mode == PropertyAccessMode::kLoad && 124 if (access_mode == PropertyAccessMode::kLoad &&
93 LookupSpecialFieldAccessor(map, name, access_info)) { 125 LookupSpecialFieldAccessor(map, name, access_info)) {
94 return true; 126 return true;
95 } 127 }
96 128
97 MaybeHandle<JSObject> holder; 129 MaybeHandle<JSObject> holder;
98 while (true) { 130 do {
99 // Lookup the named property on the {map}. 131 // Lookup the named property on the {map}.
100 Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate()); 132 Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate());
101 int const number = descriptors->SearchWithCache(*name, *map); 133 int const number = descriptors->SearchWithCache(*name, *map);
102 if (number != DescriptorArray::kNotFound) { 134 if (number != DescriptorArray::kNotFound) {
103 PropertyDetails const details = descriptors->GetDetails(number); 135 PropertyDetails const details = descriptors->GetDetails(number);
104 if (access_mode == PropertyAccessMode::kStore) { 136 if (access_mode == PropertyAccessMode::kStore) {
105 // Don't bother optimizing stores to read-only properties. 137 // Don't bother optimizing stores to read-only properties.
106 if (details.IsReadOnly()) { 138 if (details.IsReadOnly()) {
107 return false; 139 return false;
108 } 140 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 .ToHandle(&constructor)) { 212 .ToHandle(&constructor)) {
181 map = handle(constructor->initial_map(), isolate()); 213 map = handle(constructor->initial_map(), isolate());
182 DCHECK(map->prototype()->IsJSObject()); 214 DCHECK(map->prototype()->IsJSObject());
183 } else if (map->prototype()->IsNull()) { 215 } else if (map->prototype()->IsNull()) {
184 // Store to property not found on the receiver or any prototype, we need 216 // Store to property not found on the receiver or any prototype, we need
185 // to transition to a new data property. 217 // to transition to a new data property.
186 // Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver) 218 // Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver)
187 if (access_mode == PropertyAccessMode::kStore) { 219 if (access_mode == PropertyAccessMode::kStore) {
188 return LookupTransition(receiver_map, name, holder, access_info); 220 return LookupTransition(receiver_map, name, holder, access_info);
189 } 221 }
190 // TODO(bmeurer): Handle the not found case if the prototype is null. 222 // The property was not found, return undefined or throw depending
191 return false; 223 // on the language mode of the load operation.
224 // Implemented according to ES6 section 9.1.8 [[Get]] (P, Receiver)
225 *access_info = PropertyAccessInfo::NotFound(
226 Type::Class(receiver_map, zone()), holder);
227 return true;
192 } else { 228 } else {
193 return false; 229 return false;
194 } 230 }
195 } 231 }
196 Handle<JSObject> map_prototype(JSObject::cast(map->prototype()), isolate()); 232 Handle<JSObject> map_prototype(JSObject::cast(map->prototype()), isolate());
197 if (map_prototype->map()->is_deprecated()) { 233 if (map_prototype->map()->is_deprecated()) {
198 // Try to migrate the prototype object so we don't embed the deprecated 234 // Try to migrate the prototype object so we don't embed the deprecated
199 // map into the optimized code. 235 // map into the optimized code.
200 JSObject::TryMigrateInstance(map_prototype); 236 JSObject::TryMigrateInstance(map_prototype);
201 } 237 }
202 map = handle(map_prototype->map(), isolate()); 238 map = handle(map_prototype->map(), isolate());
203 holder = map_prototype; 239 holder = map_prototype;
204 240 } while (CanInlinePropertyAccess(map));
205 // Check if it is safe to inline property access for the {map}.
206 if (!CanInlinePropertyAccess(map)) return false;
207 }
208 return false; 241 return false;
209 } 242 }
210 243
211 244
245 bool PropertyAccessInfoFactory::ComputePropertyAccessInfos(
246 MapHandleList const& maps, Handle<Name> name,
247 PropertyAccessMode access_mode,
248 ZoneVector<PropertyAccessInfo>* access_infos) {
249 for (Handle<Map> map : maps) {
250 if (Map::TryUpdate(map).ToHandle(&map)) {
251 PropertyAccessInfo access_info;
252 if (!ComputePropertyAccessInfo(map, name, access_mode, &access_info)) {
253 return false;
254 }
255 access_infos->push_back(access_info);
256 }
257 }
258 return true;
259 }
260
261
212 bool PropertyAccessInfoFactory::LookupSpecialFieldAccessor( 262 bool PropertyAccessInfoFactory::LookupSpecialFieldAccessor(
213 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) { 263 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) {
214 // Check for special JSObject field accessors. 264 // Check for special JSObject field accessors.
215 int offset; 265 int offset;
216 if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) { 266 if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) {
217 FieldIndex field_index = FieldIndex::ForInObjectOffset(offset); 267 FieldIndex field_index = FieldIndex::ForInObjectOffset(offset);
218 Type* field_type = Type::Tagged(); 268 Type* field_type = Type::Tagged();
219 if (map->IsStringMap()) { 269 if (map->IsStringMap()) {
220 DCHECK(Name::Equals(factory()->length_string(), name)); 270 DCHECK(Name::Equals(factory()->length_string(), name));
221 // The String::length property is always a smi in the range 271 // The String::length property is always a smi in the range
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 dependencies()->AssumeMapNotDeprecated(transition_map); 342 dependencies()->AssumeMapNotDeprecated(transition_map);
293 *access_info = 343 *access_info =
294 PropertyAccessInfo::DataField(Type::Class(map, zone()), field_index, 344 PropertyAccessInfo::DataField(Type::Class(map, zone()), field_index,
295 field_type, holder, transition_map); 345 field_type, holder, transition_map);
296 return true; 346 return true;
297 } 347 }
298 return false; 348 return false;
299 } 349 }
300 350
301 351
302 bool PropertyAccessInfoFactory::ComputePropertyAccessInfos(
303 MapHandleList const& maps, Handle<Name> name,
304 PropertyAccessMode access_mode,
305 ZoneVector<PropertyAccessInfo>* access_infos) {
306 for (Handle<Map> map : maps) {
307 if (Map::TryUpdate(map).ToHandle(&map)) {
308 PropertyAccessInfo access_info;
309 if (!ComputePropertyAccessInfo(map, name, access_mode, &access_info)) {
310 return false;
311 }
312 access_infos->push_back(access_info);
313 }
314 }
315 return true;
316 }
317
318
319 Factory* PropertyAccessInfoFactory::factory() const { 352 Factory* PropertyAccessInfoFactory::factory() const {
320 return isolate()->factory(); 353 return isolate()->factory();
321 } 354 }
322 355
323 } // namespace compiler 356 } // namespace compiler
324 } // namespace internal 357 } // namespace internal
325 } // namespace v8 358 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/property-access-info.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698