OLD | NEW |
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/access-info.h" | 9 #include "src/compiler/access-info.h" |
10 #include "src/compiler/type-cache.h" | 10 #include "src/compiler/type-cache.h" |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 return false; | 291 return false; |
292 } | 292 } |
293 // Check for store to data property on a prototype. | 293 // Check for store to data property on a prototype. |
294 if (details.kind() == kData && !holder.is_null()) { | 294 if (details.kind() == kData && !holder.is_null()) { |
295 // Store to property not found on the receiver but on a prototype, we | 295 // Store to property not found on the receiver but on a prototype, we |
296 // need to transition to a new data property. | 296 // need to transition to a new data property. |
297 // Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver) | 297 // Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver) |
298 return LookupTransition(receiver_map, name, holder, access_info); | 298 return LookupTransition(receiver_map, name, holder, access_info); |
299 } | 299 } |
300 } | 300 } |
301 switch (details.type()) { | 301 if (details.location() == kField) { |
302 case DATA_CONSTANT: { | 302 if (details.kind() == kData) { |
303 *access_info = PropertyAccessInfo::DataConstant( | |
304 MapList{receiver_map}, | |
305 handle(descriptors->GetValue(number), isolate()), holder); | |
306 return true; | |
307 } | |
308 case DATA: { | |
309 int index = descriptors->GetFieldIndex(number); | 303 int index = descriptors->GetFieldIndex(number); |
310 Representation details_representation = details.representation(); | 304 Representation details_representation = details.representation(); |
311 FieldIndex field_index = FieldIndex::ForPropertyIndex( | 305 FieldIndex field_index = FieldIndex::ForPropertyIndex( |
312 *map, index, details_representation.IsDouble()); | 306 *map, index, details_representation.IsDouble()); |
313 Type* field_type = Type::NonInternal(); | 307 Type* field_type = Type::NonInternal(); |
314 MachineRepresentation field_representation = | 308 MachineRepresentation field_representation = |
315 MachineRepresentation::kTagged; | 309 MachineRepresentation::kTagged; |
316 MaybeHandle<Map> field_map; | 310 MaybeHandle<Map> field_map; |
317 if (details_representation.IsSmi()) { | 311 if (details_representation.IsSmi()) { |
318 field_type = Type::SignedSmall(); | 312 field_type = Type::SignedSmall(); |
(...skipping 21 matching lines...) Expand all Loading... |
340 | 334 |
341 // Remember the field map, and try to infer a useful type. | 335 // Remember the field map, and try to infer a useful type. |
342 field_type = Type::For(descriptors_field_type->AsClass()); | 336 field_type = Type::For(descriptors_field_type->AsClass()); |
343 field_map = descriptors_field_type->AsClass(); | 337 field_map = descriptors_field_type->AsClass(); |
344 } | 338 } |
345 } | 339 } |
346 *access_info = PropertyAccessInfo::DataField( | 340 *access_info = PropertyAccessInfo::DataField( |
347 MapList{receiver_map}, field_index, field_representation, | 341 MapList{receiver_map}, field_index, field_representation, |
348 field_type, field_map, holder); | 342 field_type, field_map, holder); |
349 return true; | 343 return true; |
| 344 } else { |
| 345 DCHECK_EQ(kAccessor, details.kind()); |
| 346 // TODO(turbofan): Add support for general accessors? |
| 347 return false; |
350 } | 348 } |
351 case ACCESSOR_CONSTANT: { | 349 |
| 350 } else { |
| 351 DCHECK_EQ(kDescriptor, details.location()); |
| 352 if (details.kind() == kData) { |
| 353 *access_info = PropertyAccessInfo::DataConstant( |
| 354 MapList{receiver_map}, |
| 355 handle(descriptors->GetValue(number), isolate()), holder); |
| 356 return true; |
| 357 } else { |
| 358 DCHECK_EQ(kAccessor, details.kind()); |
352 Handle<Object> accessors(descriptors->GetValue(number), isolate()); | 359 Handle<Object> accessors(descriptors->GetValue(number), isolate()); |
353 if (!accessors->IsAccessorPair()) return false; | 360 if (!accessors->IsAccessorPair()) return false; |
354 Handle<Object> accessor( | 361 Handle<Object> accessor( |
355 access_mode == AccessMode::kLoad | 362 access_mode == AccessMode::kLoad |
356 ? Handle<AccessorPair>::cast(accessors)->getter() | 363 ? Handle<AccessorPair>::cast(accessors)->getter() |
357 : Handle<AccessorPair>::cast(accessors)->setter(), | 364 : Handle<AccessorPair>::cast(accessors)->setter(), |
358 isolate()); | 365 isolate()); |
359 if (!accessor->IsJSFunction()) { | 366 if (!accessor->IsJSFunction()) { |
360 CallOptimization optimization(accessor); | 367 CallOptimization optimization(accessor); |
361 if (!optimization.is_simple_api_call()) { | 368 if (!optimization.is_simple_api_call()) { |
362 return false; | 369 return false; |
363 } | 370 } |
364 if (optimization.api_call_info()->fast_handler()->IsCode()) { | 371 if (optimization.api_call_info()->fast_handler()->IsCode()) { |
365 return false; | 372 return false; |
366 } | 373 } |
367 if (V8_UNLIKELY(FLAG_runtime_stats)) return false; | 374 if (V8_UNLIKELY(FLAG_runtime_stats)) return false; |
368 } | 375 } |
369 *access_info = PropertyAccessInfo::AccessorConstant( | 376 *access_info = PropertyAccessInfo::AccessorConstant( |
370 MapList{receiver_map}, accessor, holder); | 377 MapList{receiver_map}, accessor, holder); |
371 return true; | 378 return true; |
372 } | 379 } |
373 case ACCESSOR: { | |
374 // TODO(turbofan): Add support for general accessors? | |
375 return false; | |
376 } | |
377 } | 380 } |
378 UNREACHABLE(); | 381 UNREACHABLE(); |
379 return false; | 382 return false; |
380 } | 383 } |
381 | 384 |
382 // Don't search on the prototype chain for special indices in case of | 385 // Don't search on the prototype chain for special indices in case of |
383 // integer indexed exotic objects (see ES6 section 9.4.5). | 386 // integer indexed exotic objects (see ES6 section 9.4.5). |
384 if (map->IsJSTypedArrayMap() && name->IsString() && | 387 if (map->IsJSTypedArrayMap() && name->IsString() && |
385 IsSpecialIndex(isolate()->unicode_cache(), String::cast(*name))) { | 388 IsSpecialIndex(isolate()->unicode_cache(), String::cast(*name))) { |
386 return false; | 389 return false; |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 } | 508 } |
506 Handle<Map> transition_map; | 509 Handle<Map> transition_map; |
507 if (TransitionArray::SearchTransition(map, kData, name, NONE) | 510 if (TransitionArray::SearchTransition(map, kData, name, NONE) |
508 .ToHandle(&transition_map)) { | 511 .ToHandle(&transition_map)) { |
509 int const number = transition_map->LastAdded(); | 512 int const number = transition_map->LastAdded(); |
510 PropertyDetails const details = | 513 PropertyDetails const details = |
511 transition_map->instance_descriptors()->GetDetails(number); | 514 transition_map->instance_descriptors()->GetDetails(number); |
512 // Don't bother optimizing stores to read-only properties. | 515 // Don't bother optimizing stores to read-only properties. |
513 if (details.IsReadOnly()) return false; | 516 if (details.IsReadOnly()) return false; |
514 // TODO(bmeurer): Handle transition to data constant? | 517 // TODO(bmeurer): Handle transition to data constant? |
515 if (details.type() != DATA) return false; | 518 if (details.location() != kField) return false; |
516 int const index = details.field_index(); | 519 int const index = details.field_index(); |
517 Representation details_representation = details.representation(); | 520 Representation details_representation = details.representation(); |
518 FieldIndex field_index = FieldIndex::ForPropertyIndex( | 521 FieldIndex field_index = FieldIndex::ForPropertyIndex( |
519 *transition_map, index, details_representation.IsDouble()); | 522 *transition_map, index, details_representation.IsDouble()); |
520 Type* field_type = Type::NonInternal(); | 523 Type* field_type = Type::NonInternal(); |
521 MaybeHandle<Map> field_map; | 524 MaybeHandle<Map> field_map; |
522 MachineRepresentation field_representation = MachineRepresentation::kTagged; | 525 MachineRepresentation field_representation = MachineRepresentation::kTagged; |
523 if (details_representation.IsSmi()) { | 526 if (details_representation.IsSmi()) { |
524 field_type = Type::SignedSmall(); | 527 field_type = Type::SignedSmall(); |
525 field_representation = MachineRepresentation::kTaggedSigned; | 528 field_representation = MachineRepresentation::kTaggedSigned; |
(...skipping 29 matching lines...) Expand all Loading... |
555 } | 558 } |
556 return false; | 559 return false; |
557 } | 560 } |
558 | 561 |
559 | 562 |
560 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } | 563 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } |
561 | 564 |
562 } // namespace compiler | 565 } // namespace compiler |
563 } // namespace internal | 566 } // namespace internal |
564 } // namespace v8 | 567 } // namespace v8 |
OLD | NEW |