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

Side by Side Diff: src/interpreter/interpreter.cc

Issue 2263253002: [interpreter] Make the binary op with Smi bytecode handlers collect type feedback. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update. Created 4 years, 3 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/interpreter/bytecodes.h ('k') | src/mips/interface-descriptors-mips.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 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.h" 5 #include "src/interpreter/interpreter.h"
6 6
7 #include <fstream> 7 #include <fstream>
8 #include <memory> 8 #include <memory>
9 9
10 #include "src/ast/prettyprinter.h" 10 #include "src/ast/prettyprinter.h"
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 } 803 }
804 804
805 template <class Generator> 805 template <class Generator>
806 void Interpreter::DoBinaryOpWithFeedback(InterpreterAssembler* assembler) { 806 void Interpreter::DoBinaryOpWithFeedback(InterpreterAssembler* assembler) {
807 Node* reg_index = __ BytecodeOperandReg(0); 807 Node* reg_index = __ BytecodeOperandReg(0);
808 Node* lhs = __ LoadRegister(reg_index); 808 Node* lhs = __ LoadRegister(reg_index);
809 Node* rhs = __ GetAccumulator(); 809 Node* rhs = __ GetAccumulator();
810 Node* context = __ GetContext(); 810 Node* context = __ GetContext();
811 Node* slot_index = __ BytecodeOperandIdx(1); 811 Node* slot_index = __ BytecodeOperandIdx(1);
812 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 812 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
813 Node* result = Generator::Generate(assembler, lhs, rhs, context, 813 Node* result = Generator::Generate(assembler, lhs, rhs, slot_index,
814 type_feedback_vector, slot_index); 814 type_feedback_vector, context);
815 __ SetAccumulator(result); 815 __ SetAccumulator(result);
816 __ Dispatch(); 816 __ Dispatch();
817 } 817 }
818 818
819 // Add <src> 819 // Add <src>
820 // 820 //
821 // Add register <src> to accumulator. 821 // Add register <src> to accumulator.
822 void Interpreter::DoAdd(InterpreterAssembler* assembler) { 822 void Interpreter::DoAdd(InterpreterAssembler* assembler) {
823 DoBinaryOpWithFeedback<AddWithFeedbackStub>(assembler); 823 DoBinaryOpWithFeedback<AddWithFeedbackStub>(assembler);
824 } 824 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 // operation <reg> is the lhs operand and <imm> is the <rhs> operand. 980 // operation <reg> is the lhs operand and <imm> is the <rhs> operand.
981 void Interpreter::DoAddSmi(InterpreterAssembler* assembler) { 981 void Interpreter::DoAddSmi(InterpreterAssembler* assembler) {
982 Variable var_result(assembler, MachineRepresentation::kTagged); 982 Variable var_result(assembler, MachineRepresentation::kTagged);
983 Label fastpath(assembler), slowpath(assembler, Label::kDeferred), 983 Label fastpath(assembler), slowpath(assembler, Label::kDeferred),
984 end(assembler); 984 end(assembler);
985 985
986 Node* reg_index = __ BytecodeOperandReg(1); 986 Node* reg_index = __ BytecodeOperandReg(1);
987 Node* left = __ LoadRegister(reg_index); 987 Node* left = __ LoadRegister(reg_index);
988 Node* raw_int = __ BytecodeOperandImm(0); 988 Node* raw_int = __ BytecodeOperandImm(0);
989 Node* right = __ SmiTag(raw_int); 989 Node* right = __ SmiTag(raw_int);
990 Node* slot_index = __ BytecodeOperandIdx(2);
991 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
990 992
991 // {right} is known to be a Smi. 993 // {right} is known to be a Smi.
992 // Check if the {left} is a Smi take the fast path. 994 // Check if the {left} is a Smi take the fast path.
993 __ BranchIf(__ WordIsSmi(left), &fastpath, &slowpath); 995 __ BranchIf(__ WordIsSmi(left), &fastpath, &slowpath);
994 __ Bind(&fastpath); 996 __ Bind(&fastpath);
995 { 997 {
996 // Try fast Smi addition first. 998 // Try fast Smi addition first.
997 Node* pair = __ SmiAddWithOverflow(left, right); 999 Node* pair = __ SmiAddWithOverflow(left, right);
998 Node* overflow = __ Projection(1, pair); 1000 Node* overflow = __ Projection(1, pair);
999 1001
1000 // Check if the Smi additon overflowed. 1002 // Check if the Smi additon overflowed.
1001 Label if_notoverflow(assembler); 1003 Label if_notoverflow(assembler);
1002 __ BranchIf(overflow, &slowpath, &if_notoverflow); 1004 __ BranchIf(overflow, &slowpath, &if_notoverflow);
1003 __ Bind(&if_notoverflow); 1005 __ Bind(&if_notoverflow);
1004 { 1006 {
1007 __ UpdateFeedback(__ Int32Constant(BinaryOperationFeedback::kSignedSmall),
1008 type_feedback_vector, slot_index);
1005 var_result.Bind(__ Projection(0, pair)); 1009 var_result.Bind(__ Projection(0, pair));
1006 __ Goto(&end); 1010 __ Goto(&end);
1007 } 1011 }
1008 } 1012 }
1009 __ Bind(&slowpath); 1013 __ Bind(&slowpath);
1010 { 1014 {
1011 Node* context = __ GetContext(); 1015 Node* context = __ GetContext();
1012 Callable callable = CodeFactory::Add(__ isolate()); 1016 AddWithFeedbackStub stub(__ isolate());
1013 var_result.Bind(__ CallStub(callable, context, left, right)); 1017 Callable callable =
1018 Callable(stub.GetCode(), AddWithFeedbackStub::Descriptor(__ isolate()));
1019 Node* args[] = {left, right, slot_index, type_feedback_vector, context};
1020 var_result.Bind(__ CallStubN(callable, args, 1));
1014 __ Goto(&end); 1021 __ Goto(&end);
1015 } 1022 }
1016 __ Bind(&end); 1023 __ Bind(&end);
1017 { 1024 {
1018 __ SetAccumulator(var_result.value()); 1025 __ SetAccumulator(var_result.value());
1019 __ Dispatch(); 1026 __ Dispatch();
1020 } 1027 }
1021 } 1028 }
1022 1029
1023 // SubSmi <imm> <reg> 1030 // SubSmi <imm> <reg>
1024 // 1031 //
1025 // Subtracts an immediate value <imm> to register <reg>. For this 1032 // Subtracts an immediate value <imm> to register <reg>. For this
1026 // operation <reg> is the lhs operand and <imm> is the rhs operand. 1033 // operation <reg> is the lhs operand and <imm> is the rhs operand.
1027 void Interpreter::DoSubSmi(InterpreterAssembler* assembler) { 1034 void Interpreter::DoSubSmi(InterpreterAssembler* assembler) {
1028 Variable var_result(assembler, MachineRepresentation::kTagged); 1035 Variable var_result(assembler, MachineRepresentation::kTagged);
1029 Label fastpath(assembler), slowpath(assembler, Label::kDeferred), 1036 Label fastpath(assembler), slowpath(assembler, Label::kDeferred),
1030 end(assembler); 1037 end(assembler);
1031 1038
1032 Node* reg_index = __ BytecodeOperandReg(1); 1039 Node* reg_index = __ BytecodeOperandReg(1);
1033 Node* left = __ LoadRegister(reg_index); 1040 Node* left = __ LoadRegister(reg_index);
1034 Node* raw_int = __ BytecodeOperandImm(0); 1041 Node* raw_int = __ BytecodeOperandImm(0);
1035 Node* right = __ SmiTag(raw_int); 1042 Node* right = __ SmiTag(raw_int);
1043 Node* slot_index = __ BytecodeOperandIdx(2);
1044 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
1036 1045
1037 // {right} is known to be a Smi. 1046 // {right} is known to be a Smi.
1038 // Check if the {left} is a Smi take the fast path. 1047 // Check if the {left} is a Smi take the fast path.
1039 __ BranchIf(__ WordIsSmi(left), &fastpath, &slowpath); 1048 __ BranchIf(__ WordIsSmi(left), &fastpath, &slowpath);
1040 __ Bind(&fastpath); 1049 __ Bind(&fastpath);
1041 { 1050 {
1042 // Try fast Smi subtraction first. 1051 // Try fast Smi subtraction first.
1043 Node* pair = __ SmiSubWithOverflow(left, right); 1052 Node* pair = __ SmiSubWithOverflow(left, right);
1044 Node* overflow = __ Projection(1, pair); 1053 Node* overflow = __ Projection(1, pair);
1045 1054
1046 // Check if the Smi subtraction overflowed. 1055 // Check if the Smi subtraction overflowed.
1047 Label if_notoverflow(assembler); 1056 Label if_notoverflow(assembler);
1048 __ BranchIf(overflow, &slowpath, &if_notoverflow); 1057 __ BranchIf(overflow, &slowpath, &if_notoverflow);
1049 __ Bind(&if_notoverflow); 1058 __ Bind(&if_notoverflow);
1050 { 1059 {
1060 __ UpdateFeedback(__ Int32Constant(BinaryOperationFeedback::kSignedSmall),
1061 type_feedback_vector, slot_index);
1051 var_result.Bind(__ Projection(0, pair)); 1062 var_result.Bind(__ Projection(0, pair));
1052 __ Goto(&end); 1063 __ Goto(&end);
1053 } 1064 }
1054 } 1065 }
1055 __ Bind(&slowpath); 1066 __ Bind(&slowpath);
1056 { 1067 {
1057 Node* context = __ GetContext(); 1068 Node* context = __ GetContext();
1058 Callable callable = CodeFactory::Subtract(__ isolate()); 1069 SubtractWithFeedbackStub stub(__ isolate());
1059 var_result.Bind(__ CallStub(callable, context, left, right)); 1070 Callable callable = Callable(
1071 stub.GetCode(), SubtractWithFeedbackStub::Descriptor(__ isolate()));
1072 Node* args[] = {left, right, slot_index, type_feedback_vector, context};
1073 var_result.Bind(__ CallStubN(callable, args, 1));
1060 __ Goto(&end); 1074 __ Goto(&end);
1061 } 1075 }
1062 __ Bind(&end); 1076 __ Bind(&end);
1063 { 1077 {
1064 __ SetAccumulator(var_result.value()); 1078 __ SetAccumulator(var_result.value());
1065 __ Dispatch(); 1079 __ Dispatch();
1066 } 1080 }
1067 } 1081 }
1068 1082
1069 // BitwiseOr <imm> <reg> 1083 // BitwiseOr <imm> <reg>
1070 // 1084 //
1071 // BitwiseOr <reg> with <imm>. For this operation <reg> is the lhs 1085 // BitwiseOr <reg> with <imm>. For this operation <reg> is the lhs
1072 // operand and <imm> is the rhs operand. 1086 // operand and <imm> is the rhs operand.
1073 void Interpreter::DoBitwiseOrSmi(InterpreterAssembler* assembler) { 1087 void Interpreter::DoBitwiseOrSmi(InterpreterAssembler* assembler) {
1074 Node* reg_index = __ BytecodeOperandReg(1); 1088 Node* reg_index = __ BytecodeOperandReg(1);
1075 Node* left = __ LoadRegister(reg_index); 1089 Node* left = __ LoadRegister(reg_index);
1076 Node* raw_int = __ BytecodeOperandImm(0); 1090 Node* raw_int = __ BytecodeOperandImm(0);
1077 Node* right = __ SmiTag(raw_int); 1091 Node* right = __ SmiTag(raw_int);
1078 Node* context = __ GetContext(); 1092 Node* context = __ GetContext();
1079 Node* lhs_value = __ TruncateTaggedToWord32(context, left); 1093 Node* slot_index = __ BytecodeOperandIdx(2);
1094 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
1095 Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32);
1096 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback(
1097 context, left, &var_lhs_type_feedback);
1080 Node* rhs_value = __ SmiToWord32(right); 1098 Node* rhs_value = __ SmiToWord32(right);
1081 Node* value = __ Word32Or(lhs_value, rhs_value); 1099 Node* value = __ Word32Or(lhs_value, rhs_value);
1082 Node* result = __ ChangeInt32ToTagged(value); 1100 Node* result = __ ChangeInt32ToTagged(value);
1101 Node* result_type =
1102 __ Select(__ WordIsSmi(result),
1103 __ Int32Constant(BinaryOperationFeedback::kSignedSmall),
1104 __ Int32Constant(BinaryOperationFeedback::kNumber));
1105 __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()),
1106 type_feedback_vector, slot_index);
1083 __ SetAccumulator(result); 1107 __ SetAccumulator(result);
1084 __ Dispatch(); 1108 __ Dispatch();
1085 } 1109 }
1086 1110
1087 // BitwiseAnd <imm> <reg> 1111 // BitwiseAnd <imm> <reg>
1088 // 1112 //
1089 // BitwiseAnd <reg> with <imm>. For this operation <reg> is the lhs 1113 // BitwiseAnd <reg> with <imm>. For this operation <reg> is the lhs
1090 // operand and <imm> is the rhs operand. 1114 // operand and <imm> is the rhs operand.
1091 void Interpreter::DoBitwiseAndSmi(InterpreterAssembler* assembler) { 1115 void Interpreter::DoBitwiseAndSmi(InterpreterAssembler* assembler) {
1092 Node* reg_index = __ BytecodeOperandReg(1); 1116 Node* reg_index = __ BytecodeOperandReg(1);
1093 Node* left = __ LoadRegister(reg_index); 1117 Node* left = __ LoadRegister(reg_index);
1094 Node* raw_int = __ BytecodeOperandImm(0); 1118 Node* raw_int = __ BytecodeOperandImm(0);
1095 Node* right = __ SmiTag(raw_int); 1119 Node* right = __ SmiTag(raw_int);
1096 Node* context = __ GetContext(); 1120 Node* context = __ GetContext();
1097 Node* lhs_value = __ TruncateTaggedToWord32(context, left); 1121 Node* slot_index = __ BytecodeOperandIdx(2);
1122 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
1123 Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32);
1124 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback(
1125 context, left, &var_lhs_type_feedback);
1098 Node* rhs_value = __ SmiToWord32(right); 1126 Node* rhs_value = __ SmiToWord32(right);
1099 Node* value = __ Word32And(lhs_value, rhs_value); 1127 Node* value = __ Word32And(lhs_value, rhs_value);
1100 Node* result = __ ChangeInt32ToTagged(value); 1128 Node* result = __ ChangeInt32ToTagged(value);
1129 Node* result_type =
1130 __ Select(__ WordIsSmi(result),
1131 __ Int32Constant(BinaryOperationFeedback::kSignedSmall),
1132 __ Int32Constant(BinaryOperationFeedback::kNumber));
1133 __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()),
1134 type_feedback_vector, slot_index);
1101 __ SetAccumulator(result); 1135 __ SetAccumulator(result);
1102 __ Dispatch(); 1136 __ Dispatch();
1103 } 1137 }
1104 1138
1105 // ShiftLeftSmi <imm> <reg> 1139 // ShiftLeftSmi <imm> <reg>
1106 // 1140 //
1107 // Left shifts register <src> by the count specified in <imm>. 1141 // Left shifts register <src> by the count specified in <imm>.
1108 // Register <src> is converted to an int32 before the operation. The 5 1142 // Register <src> is converted to an int32 before the operation. The 5
1109 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F). 1143 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F).
1110 void Interpreter::DoShiftLeftSmi(InterpreterAssembler* assembler) { 1144 void Interpreter::DoShiftLeftSmi(InterpreterAssembler* assembler) {
1111 Node* reg_index = __ BytecodeOperandReg(1); 1145 Node* reg_index = __ BytecodeOperandReg(1);
1112 Node* left = __ LoadRegister(reg_index); 1146 Node* left = __ LoadRegister(reg_index);
1113 Node* raw_int = __ BytecodeOperandImm(0); 1147 Node* raw_int = __ BytecodeOperandImm(0);
1114 Node* right = __ SmiTag(raw_int); 1148 Node* right = __ SmiTag(raw_int);
1115 Node* context = __ GetContext(); 1149 Node* context = __ GetContext();
1116 Node* lhs_value = __ TruncateTaggedToWord32(context, left); 1150 Node* slot_index = __ BytecodeOperandIdx(2);
1151 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
1152 Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32);
1153 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback(
1154 context, left, &var_lhs_type_feedback);
1117 Node* rhs_value = __ SmiToWord32(right); 1155 Node* rhs_value = __ SmiToWord32(right);
1118 Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f)); 1156 Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f));
1119 Node* value = __ Word32Shl(lhs_value, shift_count); 1157 Node* value = __ Word32Shl(lhs_value, shift_count);
1120 Node* result = __ ChangeInt32ToTagged(value); 1158 Node* result = __ ChangeInt32ToTagged(value);
1159 Node* result_type =
1160 __ Select(__ WordIsSmi(result),
1161 __ Int32Constant(BinaryOperationFeedback::kSignedSmall),
1162 __ Int32Constant(BinaryOperationFeedback::kNumber));
1163 __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()),
1164 type_feedback_vector, slot_index);
1121 __ SetAccumulator(result); 1165 __ SetAccumulator(result);
1122 __ Dispatch(); 1166 __ Dispatch();
1123 } 1167 }
1124 1168
1125 // ShiftRightSmi <imm> <reg> 1169 // ShiftRightSmi <imm> <reg>
1126 // 1170 //
1127 // Right shifts register <src> by the count specified in <imm>. 1171 // Right shifts register <src> by the count specified in <imm>.
1128 // Register <src> is converted to an int32 before the operation. The 5 1172 // Register <src> is converted to an int32 before the operation. The 5
1129 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F). 1173 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F).
1130 void Interpreter::DoShiftRightSmi(InterpreterAssembler* assembler) { 1174 void Interpreter::DoShiftRightSmi(InterpreterAssembler* assembler) {
1131 Node* reg_index = __ BytecodeOperandReg(1); 1175 Node* reg_index = __ BytecodeOperandReg(1);
1132 Node* left = __ LoadRegister(reg_index); 1176 Node* left = __ LoadRegister(reg_index);
1133 Node* raw_int = __ BytecodeOperandImm(0); 1177 Node* raw_int = __ BytecodeOperandImm(0);
1134 Node* right = __ SmiTag(raw_int); 1178 Node* right = __ SmiTag(raw_int);
1135 Node* context = __ GetContext(); 1179 Node* context = __ GetContext();
1136 Node* lhs_value = __ TruncateTaggedToWord32(context, left); 1180 Node* slot_index = __ BytecodeOperandIdx(2);
1181 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
1182 Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32);
1183 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback(
1184 context, left, &var_lhs_type_feedback);
1137 Node* rhs_value = __ SmiToWord32(right); 1185 Node* rhs_value = __ SmiToWord32(right);
1138 Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f)); 1186 Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f));
1139 Node* value = __ Word32Sar(lhs_value, shift_count); 1187 Node* value = __ Word32Sar(lhs_value, shift_count);
1140 Node* result = __ ChangeInt32ToTagged(value); 1188 Node* result = __ ChangeInt32ToTagged(value);
1189 Node* result_type =
1190 __ Select(__ WordIsSmi(result),
1191 __ Int32Constant(BinaryOperationFeedback::kSignedSmall),
1192 __ Int32Constant(BinaryOperationFeedback::kNumber));
1193 __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()),
1194 type_feedback_vector, slot_index);
1141 __ SetAccumulator(result); 1195 __ SetAccumulator(result);
1142 __ Dispatch(); 1196 __ Dispatch();
1143 } 1197 }
1144 1198
1145 Node* Interpreter::BuildUnaryOp(Callable callable, 1199 Node* Interpreter::BuildUnaryOp(Callable callable,
1146 InterpreterAssembler* assembler) { 1200 InterpreterAssembler* assembler) {
1147 Node* target = __ HeapConstant(callable.code()); 1201 Node* target = __ HeapConstant(callable.code());
1148 Node* accumulator = __ GetAccumulator(); 1202 Node* accumulator = __ GetAccumulator();
1149 Node* context = __ GetContext(); 1203 Node* context = __ GetContext();
1150 return __ CallStub(callable.descriptor(), target, context, accumulator); 1204 return __ CallStub(callable.descriptor(), target, context, accumulator);
(...skipping 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after
2332 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, 2386 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset,
2333 __ SmiTag(new_state)); 2387 __ SmiTag(new_state));
2334 __ SetAccumulator(old_state); 2388 __ SetAccumulator(old_state);
2335 2389
2336 __ Dispatch(); 2390 __ Dispatch();
2337 } 2391 }
2338 2392
2339 } // namespace interpreter 2393 } // namespace interpreter
2340 } // namespace internal 2394 } // namespace internal
2341 } // namespace v8 2395 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecodes.h ('k') | src/mips/interface-descriptors-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698