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/interpreter/interpreter-assembler.h" | 5 #include "src/interpreter/interpreter-assembler.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <ostream> | 8 #include <ostream> |
9 | 9 |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 | 90 |
91 Variable cur_depth(this, MachineRepresentation::kWord32); | 91 Variable cur_depth(this, MachineRepresentation::kWord32); |
92 cur_depth.Bind(depth); | 92 cur_depth.Bind(depth); |
93 | 93 |
94 Label context_found(this); | 94 Label context_found(this); |
95 | 95 |
96 Variable* context_search_loop_variables[2] = {&cur_depth, &cur_context}; | 96 Variable* context_search_loop_variables[2] = {&cur_depth, &cur_context}; |
97 Label context_search(this, 2, context_search_loop_variables); | 97 Label context_search(this, 2, context_search_loop_variables); |
98 | 98 |
99 // Fast path if the depth is 0. | 99 // Fast path if the depth is 0. |
100 BranchIfWord32Equal(depth, Int32Constant(0), &context_found, &context_search); | 100 Branch(Word32Equal(depth, Int32Constant(0)), &context_found, &context_search); |
101 | 101 |
102 // Loop until the depth is 0. | 102 // Loop until the depth is 0. |
103 Bind(&context_search); | 103 Bind(&context_search); |
104 { | 104 { |
105 cur_depth.Bind(Int32Sub(cur_depth.value(), Int32Constant(1))); | 105 cur_depth.Bind(Int32Sub(cur_depth.value(), Int32Constant(1))); |
106 cur_context.Bind( | 106 cur_context.Bind( |
107 LoadContextSlot(cur_context.value(), Context::PREVIOUS_INDEX)); | 107 LoadContextSlot(cur_context.value(), Context::PREVIOUS_INDEX)); |
108 | 108 |
109 BranchIfWord32Equal(cur_depth.value(), Int32Constant(0), &context_found, | 109 Branch(Word32Equal(cur_depth.value(), Int32Constant(0)), &context_found, |
110 &context_search); | 110 &context_search); |
111 } | 111 } |
112 | 112 |
113 Bind(&context_found); | 113 Bind(&context_found); |
114 return cur_context.value(); | 114 return cur_context.value(); |
115 } | 115 } |
116 | 116 |
117 void InterpreterAssembler::GotoIfHasContextExtensionUpToDepth(Node* context, | 117 void InterpreterAssembler::GotoIfHasContextExtensionUpToDepth(Node* context, |
118 Node* depth, | 118 Node* depth, |
119 Label* target) { | 119 Label* target) { |
120 Variable cur_context(this, MachineRepresentation::kTaggedPointer); | 120 Variable cur_context(this, MachineRepresentation::kTaggedPointer); |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 // Slot id of 0 is used to indicate no typefeedback is available. Call using | 572 // Slot id of 0 is used to indicate no typefeedback is available. Call using |
573 // call builtin. | 573 // call builtin. |
574 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); | 574 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); |
575 Node* is_feedback_unavailable = Word32Equal(slot_id, Int32Constant(0)); | 575 Node* is_feedback_unavailable = Word32Equal(slot_id, Int32Constant(0)); |
576 GotoIf(is_feedback_unavailable, &call_without_feedback); | 576 GotoIf(is_feedback_unavailable, &call_without_feedback); |
577 | 577 |
578 // The checks. First, does function match the recorded monomorphic target? | 578 // The checks. First, does function match the recorded monomorphic target? |
579 Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id); | 579 Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id); |
580 Node* feedback_value = LoadWeakCellValue(feedback_element); | 580 Node* feedback_value = LoadWeakCellValue(feedback_element); |
581 Node* is_monomorphic = WordEqual(function, feedback_value); | 581 Node* is_monomorphic = WordEqual(function, feedback_value); |
582 BranchIf(is_monomorphic, &handle_monomorphic, &extra_checks); | 582 Branch(is_monomorphic, &handle_monomorphic, &extra_checks); |
583 | 583 |
584 Bind(&handle_monomorphic); | 584 Bind(&handle_monomorphic); |
585 { | 585 { |
586 // The compare above could have been a SMI/SMI comparison. Guard against | 586 // The compare above could have been a SMI/SMI comparison. Guard against |
587 // this convincing us that we have a monomorphic JSFunction. | 587 // this convincing us that we have a monomorphic JSFunction. |
588 Node* is_smi = TaggedIsSmi(function); | 588 Node* is_smi = TaggedIsSmi(function); |
589 GotoIf(is_smi, &extra_checks); | 589 GotoIf(is_smi, &extra_checks); |
590 | 590 |
591 // Increment the call count. | 591 // Increment the call count. |
592 IncrementCallCount(type_feedback_vector, slot_id); | 592 IncrementCallCount(type_feedback_vector, slot_id); |
(...skipping 10 matching lines...) Expand all Loading... |
603 | 603 |
604 Bind(&extra_checks); | 604 Bind(&extra_checks); |
605 { | 605 { |
606 Label check_initialized(this, Label::kDeferred), mark_megamorphic(this), | 606 Label check_initialized(this, Label::kDeferred), mark_megamorphic(this), |
607 check_allocation_site(this), | 607 check_allocation_site(this), |
608 create_allocation_site(this, Label::kDeferred); | 608 create_allocation_site(this, Label::kDeferred); |
609 // Check if it is a megamorphic target | 609 // Check if it is a megamorphic target |
610 Node* is_megamorphic = WordEqual( | 610 Node* is_megamorphic = WordEqual( |
611 feedback_element, | 611 feedback_element, |
612 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate()))); | 612 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate()))); |
613 BranchIf(is_megamorphic, &call, &check_allocation_site); | 613 Branch(is_megamorphic, &call, &check_allocation_site); |
614 | 614 |
615 Bind(&check_allocation_site); | 615 Bind(&check_allocation_site); |
616 { | 616 { |
617 Node* is_allocation_site = | 617 Node* is_allocation_site = |
618 WordEqual(LoadMap(feedback_element), | 618 WordEqual(LoadMap(feedback_element), |
619 LoadRoot(Heap::kAllocationSiteMapRootIndex)); | 619 LoadRoot(Heap::kAllocationSiteMapRootIndex)); |
620 GotoUnless(is_allocation_site, &check_initialized); | 620 GotoUnless(is_allocation_site, &check_initialized); |
621 | 621 |
622 // If it is not the Array() function, mark megamorphic. | 622 // If it is not the Array() function, mark megamorphic. |
623 Node* context_slot = | 623 Node* context_slot = |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 GotoIf(is_feedback_unavailable, &call_construct); | 774 GotoIf(is_feedback_unavailable, &call_construct); |
775 | 775 |
776 // Check that the constructor is not a smi. | 776 // Check that the constructor is not a smi. |
777 Node* is_smi = TaggedIsSmi(constructor); | 777 Node* is_smi = TaggedIsSmi(constructor); |
778 GotoIf(is_smi, &call_construct); | 778 GotoIf(is_smi, &call_construct); |
779 | 779 |
780 // Check that constructor is a JSFunction. | 780 // Check that constructor is a JSFunction. |
781 Node* instance_type = LoadInstanceType(constructor); | 781 Node* instance_type = LoadInstanceType(constructor); |
782 Node* is_js_function = | 782 Node* is_js_function = |
783 WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)); | 783 WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)); |
784 BranchIf(is_js_function, &js_function, &call_construct); | 784 Branch(is_js_function, &js_function, &call_construct); |
785 | 785 |
786 Bind(&js_function); | 786 Bind(&js_function); |
787 { | 787 { |
788 // Cache the called function in a feedback vector slot. Cache states | 788 // Cache the called function in a feedback vector slot. Cache states |
789 // are uninitialized, monomorphic (indicated by a JSFunction), and | 789 // are uninitialized, monomorphic (indicated by a JSFunction), and |
790 // megamorphic. | 790 // megamorphic. |
791 // TODO(mythria/v8:5210): Check if it is better to mark extra_checks as a | 791 // TODO(mythria/v8:5210): Check if it is better to mark extra_checks as a |
792 // deferred block so that call_construct_function will be scheduled. | 792 // deferred block so that call_construct_function will be scheduled. |
793 Label extra_checks(this), call_construct_function(this); | 793 Label extra_checks(this), call_construct_function(this); |
794 | 794 |
795 Node* feedback_element = | 795 Node* feedback_element = |
796 LoadFixedArrayElement(type_feedback_vector, slot_id); | 796 LoadFixedArrayElement(type_feedback_vector, slot_id); |
797 Node* feedback_value = LoadWeakCellValue(feedback_element); | 797 Node* feedback_value = LoadWeakCellValue(feedback_element); |
798 Node* is_monomorphic = WordEqual(constructor, feedback_value); | 798 Node* is_monomorphic = WordEqual(constructor, feedback_value); |
799 BranchIf(is_monomorphic, &call_construct_function, &extra_checks); | 799 Branch(is_monomorphic, &call_construct_function, &extra_checks); |
800 | 800 |
801 Bind(&extra_checks); | 801 Bind(&extra_checks); |
802 { | 802 { |
803 Label mark_megamorphic(this), initialize(this), | 803 Label mark_megamorphic(this), initialize(this), |
804 check_allocation_site(this), check_initialized(this), | 804 check_allocation_site(this), check_initialized(this), |
805 set_alloc_feedback_and_call(this); | 805 set_alloc_feedback_and_call(this); |
806 { | 806 { |
807 // Check if it is a megamorphic target | 807 // Check if it is a megamorphic target |
808 Comment("check if megamorphic"); | 808 Comment("check if megamorphic"); |
809 Node* is_megamorphic = WordEqual( | 809 Node* is_megamorphic = WordEqual( |
810 feedback_element, | 810 feedback_element, |
811 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate()))); | 811 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate()))); |
812 GotoIf(is_megamorphic, &call_construct_function); | 812 GotoIf(is_megamorphic, &call_construct_function); |
813 | 813 |
814 Comment("check if weak cell"); | 814 Comment("check if weak cell"); |
815 Node* is_weak_cell = WordEqual(LoadMap(feedback_element), | 815 Node* is_weak_cell = WordEqual(LoadMap(feedback_element), |
816 LoadRoot(Heap::kWeakCellMapRootIndex)); | 816 LoadRoot(Heap::kWeakCellMapRootIndex)); |
817 GotoUnless(is_weak_cell, &check_allocation_site); | 817 GotoUnless(is_weak_cell, &check_allocation_site); |
818 // If the weak cell is cleared, we have a new chance to become | 818 // If the weak cell is cleared, we have a new chance to become |
819 // monomorphic. | 819 // monomorphic. |
820 Comment("check if weak cell is cleared"); | 820 Comment("check if weak cell is cleared"); |
821 Node* is_smi = TaggedIsSmi(feedback_value); | 821 Node* is_smi = TaggedIsSmi(feedback_value); |
822 BranchIf(is_smi, &initialize, &mark_megamorphic); | 822 Branch(is_smi, &initialize, &mark_megamorphic); |
823 } | 823 } |
824 | 824 |
825 Bind(&check_allocation_site); | 825 Bind(&check_allocation_site); |
826 { | 826 { |
827 Comment("check if it is an allocation site"); | 827 Comment("check if it is an allocation site"); |
828 Node* is_allocation_site = | 828 Node* is_allocation_site = |
829 WordEqual(LoadObjectField(feedback_element, 0), | 829 WordEqual(LoadObjectField(feedback_element, 0), |
830 LoadRoot(Heap::kAllocationSiteMapRootIndex)); | 830 LoadRoot(Heap::kAllocationSiteMapRootIndex)); |
831 GotoUnless(is_allocation_site, &check_initialized); | 831 GotoUnless(is_allocation_site, &check_initialized); |
832 | 832 |
833 // Make sure the function is the Array() function | 833 // Make sure the function is the Array() function |
834 Node* context_slot = | 834 Node* context_slot = |
835 LoadFixedArrayElement(LoadNativeContext(context), | 835 LoadFixedArrayElement(LoadNativeContext(context), |
836 Int32Constant(Context::ARRAY_FUNCTION_INDEX)); | 836 Int32Constant(Context::ARRAY_FUNCTION_INDEX)); |
837 Node* is_array_function = WordEqual(context_slot, constructor); | 837 Node* is_array_function = WordEqual(context_slot, constructor); |
838 BranchIf(is_array_function, &set_alloc_feedback_and_call, | 838 Branch(is_array_function, &set_alloc_feedback_and_call, |
839 &mark_megamorphic); | 839 &mark_megamorphic); |
840 } | 840 } |
841 | 841 |
842 Bind(&set_alloc_feedback_and_call); | 842 Bind(&set_alloc_feedback_and_call); |
843 { | 843 { |
844 allocation_feedback.Bind(feedback_element); | 844 allocation_feedback.Bind(feedback_element); |
845 Goto(&call_construct_function); | 845 Goto(&call_construct_function); |
846 } | 846 } |
847 | 847 |
848 Bind(&check_initialized); | 848 Bind(&check_initialized); |
849 { | 849 { |
850 // Check if it is uninitialized. | 850 // Check if it is uninitialized. |
851 Comment("check if uninitialized"); | 851 Comment("check if uninitialized"); |
852 Node* is_uninitialized = WordEqual( | 852 Node* is_uninitialized = WordEqual( |
853 feedback_element, LoadRoot(Heap::kuninitialized_symbolRootIndex)); | 853 feedback_element, LoadRoot(Heap::kuninitialized_symbolRootIndex)); |
854 BranchIf(is_uninitialized, &initialize, &mark_megamorphic); | 854 Branch(is_uninitialized, &initialize, &mark_megamorphic); |
855 } | 855 } |
856 | 856 |
857 Bind(&initialize); | 857 Bind(&initialize); |
858 { | 858 { |
859 Label create_weak_cell(this), create_allocation_site(this); | 859 Label create_weak_cell(this), create_allocation_site(this); |
860 Comment("initialize the feedback element"); | 860 Comment("initialize the feedback element"); |
861 // Check that it is the Array() function. | 861 // Check that it is the Array() function. |
862 Node* context_slot = | 862 Node* context_slot = |
863 LoadFixedArrayElement(LoadNativeContext(context), | 863 LoadFixedArrayElement(LoadNativeContext(context), |
864 Int32Constant(Context::ARRAY_FUNCTION_INDEX)); | 864 Int32Constant(Context::ARRAY_FUNCTION_INDEX)); |
865 Node* is_array_function = WordEqual(context_slot, constructor); | 865 Node* is_array_function = WordEqual(context_slot, constructor); |
866 BranchIf(is_array_function, &create_allocation_site, &create_weak_cell); | 866 Branch(is_array_function, &create_allocation_site, &create_weak_cell); |
867 | 867 |
868 Bind(&create_allocation_site); | 868 Bind(&create_allocation_site); |
869 { | 869 { |
870 Node* site = CreateAllocationSiteInFeedbackVector( | 870 Node* site = CreateAllocationSiteInFeedbackVector( |
871 type_feedback_vector, SmiTag(slot_id)); | 871 type_feedback_vector, SmiTag(slot_id)); |
872 allocation_feedback.Bind(site); | 872 allocation_feedback.Bind(site); |
873 Goto(&call_construct_function); | 873 Goto(&call_construct_function); |
874 } | 874 } |
875 | 875 |
876 Bind(&create_weak_cell); | 876 Bind(&create_weak_cell); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 | 1000 |
1001 UpdateInterruptBudget(delta); | 1001 UpdateInterruptBudget(delta); |
1002 Node* new_bytecode_offset = Advance(delta); | 1002 Node* new_bytecode_offset = Advance(delta); |
1003 Node* target_bytecode = LoadBytecode(new_bytecode_offset); | 1003 Node* target_bytecode = LoadBytecode(new_bytecode_offset); |
1004 return DispatchToBytecode(target_bytecode, new_bytecode_offset); | 1004 return DispatchToBytecode(target_bytecode, new_bytecode_offset); |
1005 } | 1005 } |
1006 | 1006 |
1007 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { | 1007 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { |
1008 Label match(this), no_match(this); | 1008 Label match(this), no_match(this); |
1009 | 1009 |
1010 BranchIf(condition, &match, &no_match); | 1010 Branch(condition, &match, &no_match); |
1011 Bind(&match); | 1011 Bind(&match); |
1012 Jump(delta); | 1012 Jump(delta); |
1013 Bind(&no_match); | 1013 Bind(&no_match); |
1014 Dispatch(); | 1014 Dispatch(); |
1015 } | 1015 } |
1016 | 1016 |
1017 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { | 1017 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { |
1018 JumpConditional(WordEqual(lhs, rhs), delta); | 1018 JumpConditional(WordEqual(lhs, rhs), delta); |
1019 } | 1019 } |
1020 | 1020 |
(...skipping 12 matching lines...) Expand all Loading... |
1033 } | 1033 } |
1034 | 1034 |
1035 Node* InterpreterAssembler::StarDispatchLookahead(Node* target_bytecode) { | 1035 Node* InterpreterAssembler::StarDispatchLookahead(Node* target_bytecode) { |
1036 Label do_inline_star(this), done(this); | 1036 Label do_inline_star(this), done(this); |
1037 | 1037 |
1038 Variable var_bytecode(this, MachineType::PointerRepresentation()); | 1038 Variable var_bytecode(this, MachineType::PointerRepresentation()); |
1039 var_bytecode.Bind(target_bytecode); | 1039 var_bytecode.Bind(target_bytecode); |
1040 | 1040 |
1041 Node* star_bytecode = IntPtrConstant(static_cast<int>(Bytecode::kStar)); | 1041 Node* star_bytecode = IntPtrConstant(static_cast<int>(Bytecode::kStar)); |
1042 Node* is_star = WordEqual(target_bytecode, star_bytecode); | 1042 Node* is_star = WordEqual(target_bytecode, star_bytecode); |
1043 BranchIf(is_star, &do_inline_star, &done); | 1043 Branch(is_star, &do_inline_star, &done); |
1044 | 1044 |
1045 Bind(&do_inline_star); | 1045 Bind(&do_inline_star); |
1046 { | 1046 { |
1047 InlineStar(); | 1047 InlineStar(); |
1048 var_bytecode.Bind(LoadBytecode(BytecodeOffset())); | 1048 var_bytecode.Bind(LoadBytecode(BytecodeOffset())); |
1049 Goto(&done); | 1049 Goto(&done); |
1050 } | 1050 } |
1051 Bind(&done); | 1051 Bind(&done); |
1052 return var_bytecode.value(); | 1052 return var_bytecode.value(); |
1053 } | 1053 } |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1234 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { | 1234 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { |
1235 disable_stack_check_across_call_ = true; | 1235 disable_stack_check_across_call_ = true; |
1236 Node* abort_id = SmiTag(Int32Constant(bailout_reason)); | 1236 Node* abort_id = SmiTag(Int32Constant(bailout_reason)); |
1237 CallRuntime(Runtime::kAbort, GetContext(), abort_id); | 1237 CallRuntime(Runtime::kAbort, GetContext(), abort_id); |
1238 disable_stack_check_across_call_ = false; | 1238 disable_stack_check_across_call_ = false; |
1239 } | 1239 } |
1240 | 1240 |
1241 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, | 1241 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, |
1242 BailoutReason bailout_reason) { | 1242 BailoutReason bailout_reason) { |
1243 Label ok(this), abort(this, Label::kDeferred); | 1243 Label ok(this), abort(this, Label::kDeferred); |
1244 BranchIfWordEqual(lhs, rhs, &ok, &abort); | 1244 Branch(WordEqual(lhs, rhs), &ok, &abort); |
1245 | 1245 |
1246 Bind(&abort); | 1246 Bind(&abort); |
1247 Abort(bailout_reason); | 1247 Abort(bailout_reason); |
1248 Goto(&ok); | 1248 Goto(&ok); |
1249 | 1249 |
1250 Bind(&ok); | 1250 Bind(&ok); |
1251 } | 1251 } |
1252 | 1252 |
1253 void InterpreterAssembler::TraceBytecode(Runtime::FunctionId function_id) { | 1253 void InterpreterAssembler::TraceBytecode(Runtime::FunctionId function_id) { |
1254 CallRuntime(function_id, GetContext(), BytecodeArrayTaggedPointer(), | 1254 CallRuntime(function_id, GetContext(), BytecodeArrayTaggedPointer(), |
1255 SmiTag(BytecodeOffset()), GetAccumulatorUnchecked()); | 1255 SmiTag(BytecodeOffset()), GetAccumulatorUnchecked()); |
1256 } | 1256 } |
1257 | 1257 |
1258 void InterpreterAssembler::TraceBytecodeDispatch(Node* target_bytecode) { | 1258 void InterpreterAssembler::TraceBytecodeDispatch(Node* target_bytecode) { |
1259 Node* counters_table = ExternalConstant( | 1259 Node* counters_table = ExternalConstant( |
1260 ExternalReference::interpreter_dispatch_counters(isolate())); | 1260 ExternalReference::interpreter_dispatch_counters(isolate())); |
1261 Node* source_bytecode_table_index = IntPtrConstant( | 1261 Node* source_bytecode_table_index = IntPtrConstant( |
1262 static_cast<int>(bytecode_) * (static_cast<int>(Bytecode::kLast) + 1)); | 1262 static_cast<int>(bytecode_) * (static_cast<int>(Bytecode::kLast) + 1)); |
1263 | 1263 |
1264 Node* counter_offset = | 1264 Node* counter_offset = |
1265 WordShl(IntPtrAdd(source_bytecode_table_index, target_bytecode), | 1265 WordShl(IntPtrAdd(source_bytecode_table_index, target_bytecode), |
1266 IntPtrConstant(kPointerSizeLog2)); | 1266 IntPtrConstant(kPointerSizeLog2)); |
1267 Node* old_counter = | 1267 Node* old_counter = |
1268 Load(MachineType::IntPtr(), counters_table, counter_offset); | 1268 Load(MachineType::IntPtr(), counters_table, counter_offset); |
1269 | 1269 |
1270 Label counter_ok(this), counter_saturated(this, Label::kDeferred); | 1270 Label counter_ok(this), counter_saturated(this, Label::kDeferred); |
1271 | 1271 |
1272 Node* counter_reached_max = WordEqual( | 1272 Node* counter_reached_max = WordEqual( |
1273 old_counter, IntPtrConstant(std::numeric_limits<uintptr_t>::max())); | 1273 old_counter, IntPtrConstant(std::numeric_limits<uintptr_t>::max())); |
1274 BranchIf(counter_reached_max, &counter_saturated, &counter_ok); | 1274 Branch(counter_reached_max, &counter_saturated, &counter_ok); |
1275 | 1275 |
1276 Bind(&counter_ok); | 1276 Bind(&counter_ok); |
1277 { | 1277 { |
1278 Node* new_counter = IntPtrAdd(old_counter, IntPtrConstant(1)); | 1278 Node* new_counter = IntPtrAdd(old_counter, IntPtrConstant(1)); |
1279 StoreNoWriteBarrier(MachineType::PointerRepresentation(), counters_table, | 1279 StoreNoWriteBarrier(MachineType::PointerRepresentation(), counters_table, |
1280 counter_offset, new_counter); | 1280 counter_offset, new_counter); |
1281 Goto(&counter_saturated); | 1281 Goto(&counter_saturated); |
1282 } | 1282 } |
1283 | 1283 |
1284 Bind(&counter_saturated); | 1284 Bind(&counter_saturated); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 Goto(&loop); | 1371 Goto(&loop); |
1372 } | 1372 } |
1373 Bind(&done_loop); | 1373 Bind(&done_loop); |
1374 | 1374 |
1375 return array; | 1375 return array; |
1376 } | 1376 } |
1377 | 1377 |
1378 } // namespace interpreter | 1378 } // namespace interpreter |
1379 } // namespace internal | 1379 } // namespace internal |
1380 } // namespace v8 | 1380 } // namespace v8 |
OLD | NEW |