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

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 2161543002: [turbofan] Add support for eager/soft deoptimization reasons. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Do the ports properly Created 4 years, 5 months 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/assembler.cc ('k') | src/compiler/arm/code-generator-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/code-stubs.h" 5 #include "src/code-stubs.h"
6 6
7 #include "src/bailout-reason.h" 7 #include "src/bailout-reason.h"
8 #include "src/crankshaft/hydrogen.h" 8 #include "src/crankshaft/hydrogen.h"
9 #include "src/crankshaft/lithium.h" 9 #include "src/crankshaft/lithium.h"
10 #include "src/field-index.h" 10 #include "src/field-index.h"
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 UNIMPLEMENTED(); 200 UNIMPLEMENTED();
201 return NULL; 201 return NULL;
202 } 202 }
203 203
204 virtual HValue* BuildCodeUninitializedStub() { 204 virtual HValue* BuildCodeUninitializedStub() {
205 // Force a deopt that falls back to the runtime. 205 // Force a deopt that falls back to the runtime.
206 HValue* undefined = graph()->GetConstantUndefined(); 206 HValue* undefined = graph()->GetConstantUndefined();
207 IfBuilder builder(this); 207 IfBuilder builder(this);
208 builder.IfNot<HCompareObjectEqAndBranch, HValue*>(undefined, undefined); 208 builder.IfNot<HCompareObjectEqAndBranch, HValue*>(undefined, undefined);
209 builder.Then(); 209 builder.Then();
210 builder.ElseDeopt(Deoptimizer::kForcedDeoptToRuntime); 210 builder.ElseDeopt(DeoptimizeReason::kForcedDeoptToRuntime);
211 return undefined; 211 return undefined;
212 } 212 }
213 213
214 Stub* casted_stub() { return static_cast<Stub*>(stub()); } 214 Stub* casted_stub() { return static_cast<Stub*>(stub()); }
215 }; 215 };
216 216
217 217
218 Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode( 218 Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode(
219 ExternalReference miss) { 219 ExternalReference miss) {
220 Factory* factory = isolate()->factory(); 220 Factory* factory = isolate()->factory();
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 Add<HLoadNamedField>(boilerplate, nullptr, 440 Add<HLoadNamedField>(boilerplate, nullptr,
441 HObjectAccess::ForElementsPointer())); 441 HObjectAccess::ForElementsPointer()));
442 for (int offset = JSObject::kHeaderSize; offset < result_size; 442 for (int offset = JSObject::kHeaderSize; offset < result_size;
443 offset += kPointerSize) { 443 offset += kPointerSize) {
444 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(offset); 444 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(offset);
445 Add<HStoreNamedField>(result, access, 445 Add<HStoreNamedField>(result, access,
446 Add<HLoadNamedField>(boilerplate, nullptr, access)); 446 Add<HLoadNamedField>(boilerplate, nullptr, access));
447 } 447 }
448 Push(result); 448 Push(result);
449 } 449 }
450 if_notundefined.ElseDeopt(Deoptimizer::kUninitializedBoilerplateInFastClone); 450 if_notundefined.ElseDeopt(
451 DeoptimizeReason::kUninitializedBoilerplateInFastClone);
451 if_notundefined.End(); 452 if_notundefined.End();
452 453
453 return Pop(); 454 return Pop();
454 } 455 }
455 456
456 457
457 Handle<Code> FastCloneRegExpStub::GenerateCode() { 458 Handle<Code> FastCloneRegExpStub::GenerateCode() {
458 return DoGenerateCode(this); 459 return DoGenerateCode(this);
459 } 460 }
460 461
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 520
520 if_fixed.Else(); 521 if_fixed.Else();
521 Push(BuildCloneShallowArrayNonEmpty(boilerplate, 522 Push(BuildCloneShallowArrayNonEmpty(boilerplate,
522 allocation_site, 523 allocation_site,
523 alloc_site_mode, 524 alloc_site_mode,
524 FAST_DOUBLE_ELEMENTS)); 525 FAST_DOUBLE_ELEMENTS));
525 if_fixed.End(); 526 if_fixed.End();
526 if_fixed_cow.End(); 527 if_fixed_cow.End();
527 zero_capacity.End(); 528 zero_capacity.End();
528 529
529 checker.ElseDeopt(Deoptimizer::kUninitializedBoilerplateLiterals); 530 checker.ElseDeopt(DeoptimizeReason::kUninitializedBoilerplateLiterals);
530 checker.End(); 531 checker.End();
531 532
532 return environment()->Pop(); 533 return environment()->Pop();
533 } 534 }
534 535
535 536
536 Handle<Code> FastCloneShallowArrayStub::GenerateCode() { 537 Handle<Code> FastCloneShallowArrayStub::GenerateCode() {
537 return DoGenerateCode(this); 538 return DoGenerateCode(this);
538 } 539 }
539 540
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 { 693 {
693 HInstruction* argument = 694 HInstruction* argument =
694 Add<HAccessArgumentsAt>(argument_elements, argc, key); 695 Add<HAccessArgumentsAt>(argument_elements, argc, key);
695 IfBuilder can_store(this); 696 IfBuilder can_store(this);
696 can_store.IfNot<HIsSmiAndBranch>(argument); 697 can_store.IfNot<HIsSmiAndBranch>(argument);
697 if (IsFastDoubleElementsKind(kind)) { 698 if (IsFastDoubleElementsKind(kind)) {
698 can_store.And(); 699 can_store.And();
699 can_store.IfNot<HCompareMap>(argument, 700 can_store.IfNot<HCompareMap>(argument,
700 isolate()->factory()->heap_number_map()); 701 isolate()->factory()->heap_number_map());
701 } 702 }
702 can_store.ThenDeopt(Deoptimizer::kFastPathFailed); 703 can_store.ThenDeopt(DeoptimizeReason::kFastPathFailed);
703 can_store.End(); 704 can_store.End();
704 } 705 }
705 builder.EndBody(); 706 builder.EndBody();
706 } 707 }
707 708
708 HValue* length = Add<HLoadNamedField>(object, nullptr, 709 HValue* length = Add<HLoadNamedField>(object, nullptr,
709 HObjectAccess::ForArrayLength(kind)); 710 HObjectAccess::ForArrayLength(kind));
710 HValue* new_length = AddUncasted<HAdd>(length, argc); 711 HValue* new_length = AddUncasted<HAdd>(length, argc);
711 HValue* max_key = AddUncasted<HSub>(new_length, graph()->GetConstant1()); 712 HValue* max_key = AddUncasted<HSub>(new_length, graph()->GetConstant1());
712 713
(...skipping 30 matching lines...) Expand all
743 { 744 {
744 HValue* bit_field2 = 745 HValue* bit_field2 =
745 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2()); 746 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2());
746 HValue* mask = 747 HValue* mask =
747 Add<HConstant>(static_cast<int>(Map::IsPrototypeMapBits::kMask) | 748 Add<HConstant>(static_cast<int>(Map::IsPrototypeMapBits::kMask) |
748 (1 << Map::kIsExtensible)); 749 (1 << Map::kIsExtensible));
749 HValue* bits = AddUncasted<HBitwise>(Token::BIT_AND, bit_field2, mask); 750 HValue* bits = AddUncasted<HBitwise>(Token::BIT_AND, bit_field2, mask);
750 IfBuilder check(this); 751 IfBuilder check(this);
751 check.If<HCompareNumericAndBranch>( 752 check.If<HCompareNumericAndBranch>(
752 bits, Add<HConstant>(1 << Map::kIsExtensible), Token::NE); 753 bits, Add<HConstant>(1 << Map::kIsExtensible), Token::NE);
753 check.ThenDeopt(Deoptimizer::kFastPathFailed); 754 check.ThenDeopt(DeoptimizeReason::kFastPathFailed);
754 check.End(); 755 check.End();
755 } 756 }
756 757
757 // Disallow pushing onto arrays in dictionary named property mode. We need to 758 // Disallow pushing onto arrays in dictionary named property mode. We need to
758 // figure out whether the length property is still writable. 759 // figure out whether the length property is still writable.
759 { 760 {
760 HValue* bit_field3 = 761 HValue* bit_field3 =
761 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField3()); 762 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField3());
762 HValue* mask = Add<HConstant>(static_cast<int>(Map::DictionaryMap::kMask)); 763 HValue* mask = Add<HConstant>(static_cast<int>(Map::DictionaryMap::kMask));
763 HValue* bit = AddUncasted<HBitwise>(Token::BIT_AND, bit_field3, mask); 764 HValue* bit = AddUncasted<HBitwise>(Token::BIT_AND, bit_field3, mask);
764 IfBuilder check(this); 765 IfBuilder check(this);
765 check.If<HCompareNumericAndBranch>(bit, mask, Token::EQ); 766 check.If<HCompareNumericAndBranch>(bit, mask, Token::EQ);
766 check.ThenDeopt(Deoptimizer::kFastPathFailed); 767 check.ThenDeopt(DeoptimizeReason::kFastPathFailed);
767 check.End(); 768 check.End();
768 } 769 }
769 770
770 // Check whether the length property is writable. The length property is the 771 // Check whether the length property is writable. The length property is the
771 // only default named property on arrays. It's nonconfigurable, hence is 772 // only default named property on arrays. It's nonconfigurable, hence is
772 // guaranteed to stay the first property. 773 // guaranteed to stay the first property.
773 { 774 {
774 HValue* descriptors = 775 HValue* descriptors =
775 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapDescriptors()); 776 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapDescriptors());
776 HValue* details = Add<HLoadKeyed>( 777 HValue* details = Add<HLoadKeyed>(
777 descriptors, Add<HConstant>(DescriptorArray::ToDetailsIndex(0)), 778 descriptors, Add<HConstant>(DescriptorArray::ToDetailsIndex(0)),
778 nullptr, nullptr, FAST_SMI_ELEMENTS); 779 nullptr, nullptr, FAST_SMI_ELEMENTS);
779 HValue* mask = 780 HValue* mask =
780 Add<HConstant>(READ_ONLY << PropertyDetails::AttributesField::kShift); 781 Add<HConstant>(READ_ONLY << PropertyDetails::AttributesField::kShift);
781 HValue* bit = AddUncasted<HBitwise>(Token::BIT_AND, details, mask); 782 HValue* bit = AddUncasted<HBitwise>(Token::BIT_AND, details, mask);
782 IfBuilder readonly(this); 783 IfBuilder readonly(this);
783 readonly.If<HCompareNumericAndBranch>(bit, mask, Token::EQ); 784 readonly.If<HCompareNumericAndBranch>(bit, mask, Token::EQ);
784 readonly.ThenDeopt(Deoptimizer::kFastPathFailed); 785 readonly.ThenDeopt(DeoptimizeReason::kFastPathFailed);
785 readonly.End(); 786 readonly.End();
786 } 787 }
787 788
788 HValue* null = Add<HLoadRoot>(Heap::kNullValueRootIndex); 789 HValue* null = Add<HLoadRoot>(Heap::kNullValueRootIndex);
789 HValue* empty = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); 790 HValue* empty = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex);
790 environment()->Push(map); 791 environment()->Push(map);
791 LoopBuilder check_prototypes(this); 792 LoopBuilder check_prototypes(this);
792 check_prototypes.BeginBody(1); 793 check_prototypes.BeginBody(1);
793 { 794 {
794 HValue* parent_map = environment()->Pop(); 795 HValue* parent_map = environment()->Pop();
795 HValue* prototype = Add<HLoadNamedField>(parent_map, nullptr, 796 HValue* prototype = Add<HLoadNamedField>(parent_map, nullptr,
796 HObjectAccess::ForPrototype()); 797 HObjectAccess::ForPrototype());
797 798
798 IfBuilder is_null(this); 799 IfBuilder is_null(this);
799 is_null.If<HCompareObjectEqAndBranch>(prototype, null); 800 is_null.If<HCompareObjectEqAndBranch>(prototype, null);
800 is_null.Then(); 801 is_null.Then();
801 check_prototypes.Break(); 802 check_prototypes.Break();
802 is_null.End(); 803 is_null.End();
803 804
804 HValue* prototype_map = 805 HValue* prototype_map =
805 Add<HLoadNamedField>(prototype, nullptr, HObjectAccess::ForMap()); 806 Add<HLoadNamedField>(prototype, nullptr, HObjectAccess::ForMap());
806 HValue* instance_type = Add<HLoadNamedField>( 807 HValue* instance_type = Add<HLoadNamedField>(
807 prototype_map, nullptr, HObjectAccess::ForMapInstanceType()); 808 prototype_map, nullptr, HObjectAccess::ForMapInstanceType());
808 IfBuilder check_instance_type(this); 809 IfBuilder check_instance_type(this);
809 check_instance_type.If<HCompareNumericAndBranch>( 810 check_instance_type.If<HCompareNumericAndBranch>(
810 instance_type, Add<HConstant>(LAST_CUSTOM_ELEMENTS_RECEIVER), 811 instance_type, Add<HConstant>(LAST_CUSTOM_ELEMENTS_RECEIVER),
811 Token::LTE); 812 Token::LTE);
812 check_instance_type.ThenDeopt(Deoptimizer::kFastPathFailed); 813 check_instance_type.ThenDeopt(DeoptimizeReason::kFastPathFailed);
813 check_instance_type.End(); 814 check_instance_type.End();
814 815
815 HValue* elements = Add<HLoadNamedField>( 816 HValue* elements = Add<HLoadNamedField>(
816 prototype, nullptr, HObjectAccess::ForElementsPointer()); 817 prototype, nullptr, HObjectAccess::ForElementsPointer());
817 IfBuilder no_elements(this); 818 IfBuilder no_elements(this);
818 no_elements.IfNot<HCompareObjectEqAndBranch>(elements, empty); 819 no_elements.IfNot<HCompareObjectEqAndBranch>(elements, empty);
819 no_elements.ThenDeopt(Deoptimizer::kFastPathFailed); 820 no_elements.ThenDeopt(DeoptimizeReason::kFastPathFailed);
820 no_elements.End(); 821 no_elements.End();
821 822
822 environment()->Push(prototype_map); 823 environment()->Push(prototype_map);
823 } 824 }
824 check_prototypes.EndBody(); 825 check_prototypes.EndBody();
825 826
826 HValue* bit_field2 = 827 HValue* bit_field2 =
827 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2()); 828 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2());
828 HValue* kind = BuildDecodeField<Map::ElementsKindBits>(bit_field2); 829 HValue* kind = BuildDecodeField<Map::ElementsKindBits>(bit_field2);
829 830
(...skipping 29 matching lines...) Expand all
859 { 860 {
860 IfBuilder has_double_elements(this); 861 IfBuilder has_double_elements(this);
861 has_double_elements.If<HCompareNumericAndBranch>( 862 has_double_elements.If<HCompareNumericAndBranch>(
862 kind, Add<HConstant>(FAST_HOLEY_DOUBLE_ELEMENTS), Token::LTE); 863 kind, Add<HConstant>(FAST_HOLEY_DOUBLE_ELEMENTS), Token::LTE);
863 has_double_elements.Then(); 864 has_double_elements.Then();
864 { 865 {
865 HValue* new_length = BuildPushElement(object, argc, argument_elements, 866 HValue* new_length = BuildPushElement(object, argc, argument_elements,
866 FAST_HOLEY_DOUBLE_ELEMENTS); 867 FAST_HOLEY_DOUBLE_ELEMENTS);
867 environment()->Push(new_length); 868 environment()->Push(new_length);
868 } 869 }
869 has_double_elements.ElseDeopt(Deoptimizer::kFastPathFailed); 870 has_double_elements.ElseDeopt(DeoptimizeReason::kFastPathFailed);
870 has_double_elements.End(); 871 has_double_elements.End();
871 } 872 }
872 has_object_elements.End(); 873 has_object_elements.End();
873 } 874 }
874 has_smi_elements.End(); 875 has_smi_elements.End();
875 876
876 return environment()->Pop(); 877 return environment()->Pop();
877 } 878 }
878 879
879 Handle<Code> FastArrayPushStub::GenerateCode() { return DoGenerateCode(this); } 880 Handle<Code> FastArrayPushStub::GenerateCode() { return DoGenerateCode(this); }
(...skipping 11 matching lines...) Expand all
891 892
892 // Disallow binding of slow-mode functions. We need to figure out whether the 893 // Disallow binding of slow-mode functions. We need to figure out whether the
893 // length and name property are in the original state. 894 // length and name property are in the original state.
894 { 895 {
895 HValue* bit_field3 = 896 HValue* bit_field3 =
896 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField3()); 897 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField3());
897 HValue* mask = Add<HConstant>(static_cast<int>(Map::DictionaryMap::kMask)); 898 HValue* mask = Add<HConstant>(static_cast<int>(Map::DictionaryMap::kMask));
898 HValue* bit = AddUncasted<HBitwise>(Token::BIT_AND, bit_field3, mask); 899 HValue* bit = AddUncasted<HBitwise>(Token::BIT_AND, bit_field3, mask);
899 IfBuilder check(this); 900 IfBuilder check(this);
900 check.If<HCompareNumericAndBranch>(bit, mask, Token::EQ); 901 check.If<HCompareNumericAndBranch>(bit, mask, Token::EQ);
901 check.ThenDeopt(Deoptimizer::kFastPathFailed); 902 check.ThenDeopt(DeoptimizeReason::kFastPathFailed);
902 check.End(); 903 check.End();
903 } 904 }
904 905
905 // Check whether the length and name properties are still present as 906 // Check whether the length and name properties are still present as
906 // AccessorInfo objects. In that case, their value can be recomputed even if 907 // AccessorInfo objects. In that case, their value can be recomputed even if
907 // the actual value on the object changes. 908 // the actual value on the object changes.
908 { 909 {
909 HValue* descriptors = 910 HValue* descriptors =
910 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapDescriptors()); 911 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapDescriptors());
911 912
912 HValue* descriptors_length = Add<HLoadNamedField>( 913 HValue* descriptors_length = Add<HLoadNamedField>(
913 descriptors, nullptr, HObjectAccess::ForFixedArrayLength()); 914 descriptors, nullptr, HObjectAccess::ForFixedArrayLength());
914 IfBuilder range(this); 915 IfBuilder range(this);
915 range.If<HCompareNumericAndBranch>(descriptors_length, 916 range.If<HCompareNumericAndBranch>(descriptors_length,
916 graph()->GetConstant1(), Token::LTE); 917 graph()->GetConstant1(), Token::LTE);
917 range.ThenDeopt(Deoptimizer::kFastPathFailed); 918 range.ThenDeopt(DeoptimizeReason::kFastPathFailed);
918 range.End(); 919 range.End();
919 920
920 // Verify .length. 921 // Verify .length.
921 const int length_index = JSFunction::kLengthDescriptorIndex; 922 const int length_index = JSFunction::kLengthDescriptorIndex;
922 HValue* maybe_length = Add<HLoadKeyed>( 923 HValue* maybe_length = Add<HLoadKeyed>(
923 descriptors, Add<HConstant>(DescriptorArray::ToKeyIndex(length_index)), 924 descriptors, Add<HConstant>(DescriptorArray::ToKeyIndex(length_index)),
924 nullptr, nullptr, FAST_ELEMENTS); 925 nullptr, nullptr, FAST_ELEMENTS);
925 Unique<Name> length_string = Unique<Name>::CreateUninitialized( 926 Unique<Name> length_string = Unique<Name>::CreateUninitialized(
926 isolate()->factory()->length_string()); 927 isolate()->factory()->length_string());
927 Add<HCheckValue>(maybe_length, length_string, false); 928 Add<HCheckValue>(maybe_length, length_string, false);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 985
985 // Verify that __proto__ matches that of a the target bound function. 986 // Verify that __proto__ matches that of a the target bound function.
986 { 987 {
987 HValue* prototype = 988 HValue* prototype =
988 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForPrototype()); 989 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForPrototype());
989 HValue* expected_prototype = Add<HLoadNamedField>( 990 HValue* expected_prototype = Add<HLoadNamedField>(
990 bound_function_map, nullptr, HObjectAccess::ForPrototype()); 991 bound_function_map, nullptr, HObjectAccess::ForPrototype());
991 IfBuilder equal_prototype(this); 992 IfBuilder equal_prototype(this);
992 equal_prototype.IfNot<HCompareObjectEqAndBranch>(prototype, 993 equal_prototype.IfNot<HCompareObjectEqAndBranch>(prototype,
993 expected_prototype); 994 expected_prototype);
994 equal_prototype.ThenDeopt(Deoptimizer::kFastPathFailed); 995 equal_prototype.ThenDeopt(DeoptimizeReason::kFastPathFailed);
995 equal_prototype.End(); 996 equal_prototype.End();
996 } 997 }
997 998
998 // Allocate the arguments array. 999 // Allocate the arguments array.
999 IfBuilder empty_args(this); 1000 IfBuilder empty_args(this);
1000 empty_args.If<HCompareNumericAndBranch>(argc, graph()->GetConstant1(), 1001 empty_args.If<HCompareNumericAndBranch>(argc, graph()->GetConstant1(),
1001 Token::LTE); 1002 Token::LTE);
1002 empty_args.Then(); 1003 empty_args.Then();
1003 { environment()->Push(Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex)); } 1004 { environment()->Push(Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex)); }
1004 empty_args.Else(); 1005 empty_args.Else();
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 Token::LT); 1175 Token::LT);
1175 in_unmapped_range.Then(); 1176 in_unmapped_range.Then();
1176 { 1177 {
1177 if (value == NULL) { 1178 if (value == NULL) {
1178 result = Add<HLoadKeyed>(backing_store, key, nullptr, nullptr, 1179 result = Add<HLoadKeyed>(backing_store, key, nullptr, nullptr,
1179 FAST_HOLEY_ELEMENTS, NEVER_RETURN_HOLE); 1180 FAST_HOLEY_ELEMENTS, NEVER_RETURN_HOLE);
1180 } else { 1181 } else {
1181 Add<HStoreKeyed>(backing_store, key, value, nullptr, FAST_HOLEY_ELEMENTS); 1182 Add<HStoreKeyed>(backing_store, key, value, nullptr, FAST_HOLEY_ELEMENTS);
1182 } 1183 }
1183 } 1184 }
1184 in_unmapped_range.ElseDeopt(Deoptimizer::kOutsideOfRange); 1185 in_unmapped_range.ElseDeopt(DeoptimizeReason::kOutsideOfRange);
1185 in_unmapped_range.End(); 1186 in_unmapped_range.End();
1186 return result; 1187 return result;
1187 } 1188 }
1188 1189
1189 1190
1190 HValue* CodeStubGraphBuilderBase::EmitKeyedSloppyArguments(HValue* receiver, 1191 HValue* CodeStubGraphBuilderBase::EmitKeyedSloppyArguments(HValue* receiver,
1191 HValue* key, 1192 HValue* key,
1192 HValue* value) { 1193 HValue* value) {
1193 // Mapped arguments are actual arguments. Unmapped arguments are values added 1194 // Mapped arguments are actual arguments. Unmapped arguments are values added
1194 // to the arguments object after it was created for the call. Mapped arguments 1195 // to the arguments object after it was created for the call. Mapped arguments
(...skipping 20 matching lines...) Expand all
1215 // in the unmapped arguments array, as described above. Otherwise, t is a Smi 1216 // in the unmapped arguments array, as described above. Otherwise, t is a Smi
1216 // index into the context array given at elements[0]. Return the value at 1217 // index into the context array given at elements[0]. Return the value at
1217 // context[t]. 1218 // context[t].
1218 1219
1219 bool is_load = value == NULL; 1220 bool is_load = value == NULL;
1220 1221
1221 key = AddUncasted<HForceRepresentation>(key, Representation::Smi()); 1222 key = AddUncasted<HForceRepresentation>(key, Representation::Smi());
1222 IfBuilder positive_smi(this); 1223 IfBuilder positive_smi(this);
1223 positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(), 1224 positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(),
1224 Token::LT); 1225 Token::LT);
1225 positive_smi.ThenDeopt(Deoptimizer::kKeyIsNegative); 1226 positive_smi.ThenDeopt(DeoptimizeReason::kKeyIsNegative);
1226 positive_smi.End(); 1227 positive_smi.End();
1227 1228
1228 HValue* constant_two = Add<HConstant>(2); 1229 HValue* constant_two = Add<HConstant>(2);
1229 HValue* elements = AddLoadElements(receiver, nullptr); 1230 HValue* elements = AddLoadElements(receiver, nullptr);
1230 HValue* elements_length = Add<HLoadNamedField>( 1231 HValue* elements_length = Add<HLoadNamedField>(
1231 elements, nullptr, HObjectAccess::ForFixedArrayLength()); 1232 elements, nullptr, HObjectAccess::ForFixedArrayLength());
1232 HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two); 1233 HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two);
1233 IfBuilder in_range(this); 1234 IfBuilder in_range(this);
1234 in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT); 1235 in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT);
1235 in_range.Then(); 1236 in_range.Then();
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
1800 HValue* global = 1801 HValue* global =
1801 Add<HLoadNamedField>(proxy_map, nullptr, HObjectAccess::ForPrototype()); 1802 Add<HLoadNamedField>(proxy_map, nullptr, HObjectAccess::ForPrototype());
1802 HValue* map_cell = Add<HConstant>(isolate()->factory()->NewWeakCell( 1803 HValue* map_cell = Add<HConstant>(isolate()->factory()->NewWeakCell(
1803 StoreGlobalStub::global_map_placeholder(isolate()))); 1804 StoreGlobalStub::global_map_placeholder(isolate())));
1804 HValue* expected_map = Add<HLoadNamedField>( 1805 HValue* expected_map = Add<HLoadNamedField>(
1805 map_cell, nullptr, HObjectAccess::ForWeakCellValue()); 1806 map_cell, nullptr, HObjectAccess::ForWeakCellValue());
1806 HValue* map = 1807 HValue* map =
1807 Add<HLoadNamedField>(global, nullptr, HObjectAccess::ForMap()); 1808 Add<HLoadNamedField>(global, nullptr, HObjectAccess::ForMap());
1808 IfBuilder map_check(this); 1809 IfBuilder map_check(this);
1809 map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map); 1810 map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map);
1810 map_check.ThenDeopt(Deoptimizer::kUnknownMap); 1811 map_check.ThenDeopt(DeoptimizeReason::kUnknownMap);
1811 map_check.End(); 1812 map_check.End();
1812 } 1813 }
1813 1814
1814 HValue* weak_cell = Add<HConstant>(isolate()->factory()->NewWeakCell( 1815 HValue* weak_cell = Add<HConstant>(isolate()->factory()->NewWeakCell(
1815 StoreGlobalStub::property_cell_placeholder(isolate()))); 1816 StoreGlobalStub::property_cell_placeholder(isolate())));
1816 HValue* cell = Add<HLoadNamedField>(weak_cell, nullptr, 1817 HValue* cell = Add<HLoadNamedField>(weak_cell, nullptr,
1817 HObjectAccess::ForWeakCellValue()); 1818 HObjectAccess::ForWeakCellValue());
1818 Add<HCheckHeapObject>(cell); 1819 Add<HCheckHeapObject>(cell);
1819 HObjectAccess access = HObjectAccess::ForPropertyCellValue(); 1820 HObjectAccess access = HObjectAccess::ForPropertyCellValue();
1820 // Load the payload of the global parameter cell. A hole indicates that the 1821 // Load the payload of the global parameter cell. A hole indicates that the
1821 // cell has been invalidated and that the store must be handled by the 1822 // cell has been invalidated and that the store must be handled by the
1822 // runtime. 1823 // runtime.
1823 HValue* cell_contents = Add<HLoadNamedField>(cell, nullptr, access); 1824 HValue* cell_contents = Add<HLoadNamedField>(cell, nullptr, access);
1824 1825
1825 auto cell_type = stub->cell_type(); 1826 auto cell_type = stub->cell_type();
1826 if (cell_type == PropertyCellType::kConstant || 1827 if (cell_type == PropertyCellType::kConstant ||
1827 cell_type == PropertyCellType::kUndefined) { 1828 cell_type == PropertyCellType::kUndefined) {
1828 // This is always valid for all states a cell can be in. 1829 // This is always valid for all states a cell can be in.
1829 IfBuilder builder(this); 1830 IfBuilder builder(this);
1830 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); 1831 builder.If<HCompareObjectEqAndBranch>(cell_contents, value);
1831 builder.Then(); 1832 builder.Then();
1832 builder.ElseDeopt( 1833 builder.ElseDeopt(
1833 Deoptimizer::kUnexpectedCellContentsInConstantGlobalStore); 1834 DeoptimizeReason::kUnexpectedCellContentsInConstantGlobalStore);
1834 builder.End(); 1835 builder.End();
1835 } else { 1836 } else {
1836 IfBuilder builder(this); 1837 IfBuilder builder(this);
1837 HValue* hole_value = graph()->GetConstantHole(); 1838 HValue* hole_value = graph()->GetConstantHole();
1838 builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value); 1839 builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value);
1839 builder.Then(); 1840 builder.Then();
1840 builder.Deopt(Deoptimizer::kUnexpectedCellContentsInGlobalStore); 1841 builder.Deopt(DeoptimizeReason::kUnexpectedCellContentsInGlobalStore);
1841 builder.Else(); 1842 builder.Else();
1842 // When dealing with constant types, the type may be allowed to change, as 1843 // When dealing with constant types, the type may be allowed to change, as
1843 // long as optimized code remains valid. 1844 // long as optimized code remains valid.
1844 if (cell_type == PropertyCellType::kConstantType) { 1845 if (cell_type == PropertyCellType::kConstantType) {
1845 switch (stub->constant_type()) { 1846 switch (stub->constant_type()) {
1846 case PropertyCellConstantType::kSmi: 1847 case PropertyCellConstantType::kSmi:
1847 access = access.WithRepresentation(Representation::Smi()); 1848 access = access.WithRepresentation(Representation::Smi());
1848 break; 1849 break;
1849 case PropertyCellConstantType::kStableMap: { 1850 case PropertyCellConstantType::kStableMap: {
1850 // It is sufficient here to check that the value and cell contents 1851 // It is sufficient here to check that the value and cell contents
1851 // have identical maps, no matter if they are stable or not or if they 1852 // have identical maps, no matter if they are stable or not or if they
1852 // are the maps that were originally in the cell or not. If optimized 1853 // are the maps that were originally in the cell or not. If optimized
1853 // code will deopt when a cell has a unstable map and if it has a 1854 // code will deopt when a cell has a unstable map and if it has a
1854 // dependency on a stable map, it will deopt if the map destabilizes. 1855 // dependency on a stable map, it will deopt if the map destabilizes.
1855 Add<HCheckHeapObject>(value); 1856 Add<HCheckHeapObject>(value);
1856 Add<HCheckHeapObject>(cell_contents); 1857 Add<HCheckHeapObject>(cell_contents);
1857 HValue* expected_map = Add<HLoadNamedField>(cell_contents, nullptr, 1858 HValue* expected_map = Add<HLoadNamedField>(cell_contents, nullptr,
1858 HObjectAccess::ForMap()); 1859 HObjectAccess::ForMap());
1859 HValue* map = 1860 HValue* map =
1860 Add<HLoadNamedField>(value, nullptr, HObjectAccess::ForMap()); 1861 Add<HLoadNamedField>(value, nullptr, HObjectAccess::ForMap());
1861 IfBuilder map_check(this); 1862 IfBuilder map_check(this);
1862 map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map); 1863 map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map);
1863 map_check.ThenDeopt(Deoptimizer::kUnknownMap); 1864 map_check.ThenDeopt(DeoptimizeReason::kUnknownMap);
1864 map_check.End(); 1865 map_check.End();
1865 access = access.WithRepresentation(Representation::HeapObject()); 1866 access = access.WithRepresentation(Representation::HeapObject());
1866 break; 1867 break;
1867 } 1868 }
1868 } 1869 }
1869 } 1870 }
1870 Add<HStoreNamedField>(cell, access, value); 1871 Add<HStoreNamedField>(cell, access, value);
1871 builder.End(); 1872 builder.End();
1872 } 1873 }
1873 1874
1874 return value; 1875 return value;
1875 } 1876 }
1876 1877
1877 1878
1878 Handle<Code> StoreGlobalStub::GenerateCode() { 1879 Handle<Code> StoreGlobalStub::GenerateCode() {
1879 return DoGenerateCode(this); 1880 return DoGenerateCode(this);
1880 } 1881 }
1881 1882
1882 1883
1883 template <> 1884 template <>
1884 HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() { 1885 HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
1885 HValue* object = GetParameter(StoreTransitionHelper::ReceiverIndex()); 1886 HValue* object = GetParameter(StoreTransitionHelper::ReceiverIndex());
1886 HValue* key = GetParameter(StoreTransitionHelper::NameIndex()); 1887 HValue* key = GetParameter(StoreTransitionHelper::NameIndex());
1887 HValue* value = GetParameter(StoreTransitionHelper::ValueIndex()); 1888 HValue* value = GetParameter(StoreTransitionHelper::ValueIndex());
1888 HValue* map = GetParameter(StoreTransitionHelper::MapIndex()); 1889 HValue* map = GetParameter(StoreTransitionHelper::MapIndex());
1889 1890
1890 if (FLAG_trace_elements_transitions) { 1891 if (FLAG_trace_elements_transitions) {
1891 // Tracing elements transitions is the job of the runtime. 1892 // Tracing elements transitions is the job of the runtime.
1892 Add<HDeoptimize>(Deoptimizer::kTracingElementsTransitions, 1893 Add<HDeoptimize>(DeoptimizeReason::kTracingElementsTransitions,
1893 Deoptimizer::EAGER); 1894 Deoptimizer::EAGER);
1894 } else { 1895 } else {
1895 info()->MarkAsSavesCallerDoubles(); 1896 info()->MarkAsSavesCallerDoubles();
1896 1897
1897 BuildTransitionElementsKind(object, map, 1898 BuildTransitionElementsKind(object, map,
1898 casted_stub()->from_kind(), 1899 casted_stub()->from_kind(),
1899 casted_stub()->to_kind(), 1900 casted_stub()->to_kind(),
1900 casted_stub()->is_jsarray()); 1901 casted_stub()->is_jsarray());
1901 1902
1902 BuildUncheckedMonomorphicElementAccess(object, key, value, 1903 BuildUncheckedMonomorphicElementAccess(object, key, value,
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2077 Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash)); 2078 Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash));
2078 } 2079 }
2079 kind_if.Else(); 2080 kind_if.Else();
2080 2081
2081 // The SLOW_SLOPPY_ARGUMENTS_ELEMENTS check generates a "kind_if.Then" 2082 // The SLOW_SLOPPY_ARGUMENTS_ELEMENTS check generates a "kind_if.Then"
2082 STATIC_ASSERT(FAST_SLOPPY_ARGUMENTS_ELEMENTS < 2083 STATIC_ASSERT(FAST_SLOPPY_ARGUMENTS_ELEMENTS <
2083 SLOW_SLOPPY_ARGUMENTS_ELEMENTS); 2084 SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
2084 BuildElementsKindLimitCheck(&kind_if, bit_field2, 2085 BuildElementsKindLimitCheck(&kind_if, bit_field2,
2085 SLOW_SLOPPY_ARGUMENTS_ELEMENTS); 2086 SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
2086 // Non-strict elements are not handled. 2087 // Non-strict elements are not handled.
2087 Add<HDeoptimize>(Deoptimizer::kNonStrictElementsInKeyedLoadGenericStub, 2088 Add<HDeoptimize>(DeoptimizeReason::kNonStrictElementsInKeyedLoadGenericStub,
2088 Deoptimizer::EAGER); 2089 Deoptimizer::EAGER);
2089 Push(graph()->GetConstant0()); 2090 Push(graph()->GetConstant0());
2090 2091
2091 kind_if.ElseDeopt( 2092 kind_if.ElseDeopt(
2092 Deoptimizer::kElementsKindUnhandledInKeyedLoadGenericStub); 2093 DeoptimizeReason::kElementsKindUnhandledInKeyedLoadGenericStub);
2093 2094
2094 kind_if.End(); 2095 kind_if.End();
2095 } 2096 }
2096 index_name_split.Else(); 2097 index_name_split.Else();
2097 { 2098 {
2098 // Key is a unique string. 2099 // Key is a unique string.
2099 key = Pop(); 2100 key = Pop();
2100 2101
2101 int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) | 2102 int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) |
2102 (1 << Map::kHasNamedInterceptor); 2103 (1 << Map::kHasNamedInterceptor);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2207 return Pop(); 2208 return Pop();
2208 } 2209 }
2209 2210
2210 2211
2211 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2212 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2212 return DoGenerateCode(this); 2213 return DoGenerateCode(this);
2213 } 2214 }
2214 2215
2215 } // namespace internal 2216 } // namespace internal
2216 } // namespace v8 2217 } // namespace v8
OLDNEW
« no previous file with comments | « src/assembler.cc ('k') | src/compiler/arm/code-generator-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698