| 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 |