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 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 if (mreceiver.HasValue() && mreceiver.Value()->IsString()) { | 681 if (mreceiver.HasValue() && mreceiver.Value()->IsString()) { |
682 Handle<String> string = Handle<String>::cast(mreceiver.Value()); | 682 Handle<String> string = Handle<String>::cast(mreceiver.Value()); |
683 | 683 |
684 // We can only assume that the {index} is a valid array index if the IC | 684 // We can only assume that the {index} is a valid array index if the IC |
685 // is in element access mode and not MEGAMORPHIC, otherwise there's no | 685 // is in element access mode and not MEGAMORPHIC, otherwise there's no |
686 // guard for the bounds check below. | 686 // guard for the bounds check below. |
687 if (nexus.ic_state() != MEGAMORPHIC && nexus.GetKeyType() == ELEMENT) { | 687 if (nexus.ic_state() != MEGAMORPHIC && nexus.GetKeyType() == ELEMENT) { |
688 // Strings are immutable in JavaScript. | 688 // Strings are immutable in JavaScript. |
689 if (access_mode == AccessMode::kStore) return NoChange(); | 689 if (access_mode == AccessMode::kStore) return NoChange(); |
690 | 690 |
691 // Ensure that {index} is less than {receiver} length. | 691 // Properly deal with constant {index}. |
692 Node* length = jsgraph()->Constant(string->length()); | 692 NumberMatcher mindex(index); |
693 index = effect = graph()->NewNode(simplified()->CheckBounds(), index, | 693 if (mindex.IsInteger() && mindex.IsInRange(0.0, string->length() - 1)) { |
694 length, effect, control); | 694 // Constant-fold the {index} access to {string}. |
| 695 Node* value = |
| 696 jsgraph()->Constant(string->Get(static_cast<int>(mindex.Value()))); |
| 697 ReplaceWithValue(node, value, effect, control); |
| 698 return Replace(value); |
| 699 } else if (flags() & kDeoptimizationEnabled) { |
| 700 // Ensure that {index} is less than {receiver} length. |
| 701 Node* length = jsgraph()->Constant(string->length()); |
| 702 index = effect = graph()->NewNode(simplified()->CheckBounds(), index, |
| 703 length, effect, control); |
695 | 704 |
696 // Load the character from the {receiver}. | 705 // Load the character from the {receiver}. |
697 value = graph()->NewNode(simplified()->StringCharCodeAt(), receiver, | 706 value = graph()->NewNode(simplified()->StringCharCodeAt(), receiver, |
698 index, control); | 707 index, control); |
699 | 708 |
700 // Return it as a single character string. | 709 // Return it as a single character string. |
701 value = graph()->NewNode(simplified()->StringFromCharCode(), value); | 710 value = graph()->NewNode(simplified()->StringFromCharCode(), value); |
702 ReplaceWithValue(node, value, effect, control); | 711 ReplaceWithValue(node, value, effect, control); |
703 return Replace(value); | 712 return Replace(value); |
| 713 } |
704 } | 714 } |
705 } | 715 } |
706 | 716 |
707 // Check if the {nexus} reports type feedback for the IC. | 717 // Check if the {nexus} reports type feedback for the IC. |
708 if (nexus.IsUninitialized()) { | 718 if (nexus.IsUninitialized()) { |
709 if ((flags() & kDeoptimizationEnabled) && | 719 if ((flags() & kDeoptimizationEnabled) && |
710 (flags() & kBailoutOnUninitialized)) { | 720 (flags() & kBailoutOnUninitialized)) { |
711 return ReduceSoftDeoptimize( | 721 return ReduceSoftDeoptimize( |
712 node, | 722 node, |
713 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); | 723 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); |
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1623 return jsgraph()->javascript(); | 1633 return jsgraph()->javascript(); |
1624 } | 1634 } |
1625 | 1635 |
1626 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1636 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1627 return jsgraph()->simplified(); | 1637 return jsgraph()->simplified(); |
1628 } | 1638 } |
1629 | 1639 |
1630 } // namespace compiler | 1640 } // namespace compiler |
1631 } // namespace internal | 1641 } // namespace internal |
1632 } // namespace v8 | 1642 } // namespace v8 |
OLD | NEW |