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 "src/compiler/js-native-context-specialization.h" | 5 #include "src/compiler/js-native-context-specialization.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
465 return NoChange(); | 465 return NoChange(); |
466 } | 466 } |
467 | 467 |
468 // Nothing to do if we have no non-deprecated maps. | 468 // Nothing to do if we have no non-deprecated maps. |
469 if (access_infos.empty()) { | 469 if (access_infos.empty()) { |
470 return ReduceSoftDeoptimize( | 470 return ReduceSoftDeoptimize( |
471 node, | 471 node, |
472 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); | 472 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); |
473 } | 473 } |
474 | 474 |
475 // For holey stores or growing stores, we need to check that the prototype | |
476 // chain contains no setters for elements, and we need to guard those checks | |
477 // via code dependencies on the relevant prototype maps. | |
478 if (access_mode == AccessMode::kStore) { | |
479 ZoneVector<Handle<Map>> prototype_maps(zone()); | |
480 for (ElementAccessInfo const& access_info : access_infos) { | |
481 for (Handle<Map> receiver_map : access_info.receiver_maps()) { | |
482 // If the {receiver_map} has a prototype and it's elements backing | |
483 // store is either holey, or we have a potentially growing store, | |
484 // then we need to check that all prototypes have stable maps with | |
485 // fast elements (and we need to guard against changes to that below). | |
486 if (!receiver_map->prototype()->IsNull(isolate()) && | |
Toon Verwaest
2016/08/10 05:38:36
drop this null check, already covered in the loop
Benedikt Meurer
2016/08/10 05:41:46
Done.
| |
487 (IsHoleyElementsKind(receiver_map->elements_kind()) || | |
488 IsGrowStoreMode(store_mode))) { | |
489 // Make sure all prototypes are stable and have fast elements. | |
490 for (Handle<Map> map = receiver_map;;) { | |
491 Handle<Object> map_prototype(map->prototype(), isolate()); | |
492 if (map_prototype->IsNull(isolate())) break; | |
493 if (!map_prototype->IsJSObject()) return NoChange(); | |
494 map = handle(Handle<JSObject>::cast(map_prototype)->map(), | |
Toon Verwaest
2016/08/10 05:38:36
JSObject::cast(*map_prototype)->map() is shorter :
Benedikt Meurer
2016/08/10 05:41:46
Acknowledged.
| |
495 isolate()); | |
496 if (!map->is_stable()) return NoChange(); | |
497 if (!IsFastElementsKind(map->elements_kind())) return NoChange(); | |
498 prototype_maps.push_back(map); | |
Toon Verwaest
2016/08/10 05:38:36
Most of the time this will only cover array_protot
Benedikt Meurer
2016/08/10 05:41:46
Added a TODO.
| |
499 } | |
500 } | |
501 } | |
502 } | |
503 | |
504 // Install dependencies on the relevant prototype maps. | |
505 for (Handle<Map> prototype_map : prototype_maps) { | |
506 dependencies()->AssumeMapStable(prototype_map); | |
507 } | |
508 } | |
509 | |
475 // Ensure that {receiver} is a heap object. | 510 // Ensure that {receiver} is a heap object. |
476 effect = BuildCheckTaggedPointer(receiver, effect, control); | 511 effect = BuildCheckTaggedPointer(receiver, effect, control); |
477 | 512 |
478 // Check for the monomorphic case. | 513 // Check for the monomorphic case. |
479 if (access_infos.size() == 1) { | 514 if (access_infos.size() == 1) { |
480 ElementAccessInfo access_info = access_infos.front(); | 515 ElementAccessInfo access_info = access_infos.front(); |
481 | 516 |
482 // Perform possible elements kind transitions. | 517 // Perform possible elements kind transitions. |
483 for (auto transition : access_info.transitions()) { | 518 for (auto transition : access_info.transitions()) { |
484 Handle<Map> const transition_source = transition.first; | 519 Handle<Map> const transition_source = transition.first; |
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1447 } | 1482 } |
1448 | 1483 |
1449 | 1484 |
1450 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1485 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1451 return jsgraph()->simplified(); | 1486 return jsgraph()->simplified(); |
1452 } | 1487 } |
1453 | 1488 |
1454 } // namespace compiler | 1489 } // namespace compiler |
1455 } // namespace internal | 1490 } // namespace internal |
1456 } // namespace v8 | 1491 } // namespace v8 |
OLD | NEW |