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

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

Issue 1370893002: [Interpreter] Add support for short (16 bit) operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years, 2 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/interpreter/interpreter.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/bytecodes.h" 5 #include "src/interpreter/bytecodes.h"
6 6
7 #include "src/frames.h" 7 #include "src/frames.h"
8 #include "src/interpreter/bytecode-traits.h"
8 9
9 namespace v8 { 10 namespace v8 {
10 namespace internal { 11 namespace internal {
11 namespace interpreter { 12 namespace interpreter {
12 13
13 // Maximum number of operands a bytecode may have.
14 static const int kMaxOperands = 3;
15
16 // kBytecodeTable relies on kNone being the same as zero to detect length.
17 STATIC_ASSERT(static_cast<int>(OperandType::kNone) == 0);
18
19 static const OperandType kBytecodeTable[][kMaxOperands] = {
20 #define DECLARE_OPERAND(_, ...) \
21 { __VA_ARGS__ } \
22 ,
23 BYTECODE_LIST(DECLARE_OPERAND)
24 #undef DECLARE_OPERAND
25 };
26
27 14
28 // static 15 // static
29 const char* Bytecodes::ToString(Bytecode bytecode) { 16 const char* Bytecodes::ToString(Bytecode bytecode) {
30 switch (bytecode) { 17 switch (bytecode) {
31 #define CASE(Name, ...) \ 18 #define CASE(Name, ...) \
32 case Bytecode::k##Name: \ 19 case Bytecode::k##Name: \
33 return #Name; 20 return #Name;
34 BYTECODE_LIST(CASE) 21 BYTECODE_LIST(CASE)
35 #undef CASE 22 #undef CASE
36 } 23 }
37 UNREACHABLE(); 24 UNREACHABLE();
38 return ""; 25 return "";
39 } 26 }
40 27
41 28
42 // static 29 // static
43 const char* Bytecodes::OperandTypeToString(OperandType operand_type) { 30 const char* Bytecodes::OperandTypeToString(OperandType operand_type) {
44 switch (operand_type) { 31 switch (operand_type) {
45 #define CASE(Name) \ 32 #define CASE(Name, _) \
46 case OperandType::k##Name: \ 33 case OperandType::k##Name: \
47 return #Name; 34 return #Name;
48 OPERAND_TYPE_LIST(CASE) 35 OPERAND_TYPE_LIST(CASE)
49 #undef CASE 36 #undef CASE
50 } 37 }
51 UNREACHABLE(); 38 UNREACHABLE();
52 return ""; 39 return "";
53 } 40 }
54 41
55 42
56 // static 43 // static
44 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) {
45 switch (operand_size) {
46 case OperandSize::kNone:
47 return "None";
48 case OperandSize::kByte:
49 return "Byte";
50 case OperandSize::kShort:
51 return "Short";
52 }
53 UNREACHABLE();
54 return "";
55 }
56
57
58 // static
57 uint8_t Bytecodes::ToByte(Bytecode bytecode) { 59 uint8_t Bytecodes::ToByte(Bytecode bytecode) {
58 return static_cast<uint8_t>(bytecode); 60 return static_cast<uint8_t>(bytecode);
59 } 61 }
60 62
61 63
62 // static 64 // static
63 Bytecode Bytecodes::FromByte(uint8_t value) { 65 Bytecode Bytecodes::FromByte(uint8_t value) {
64 Bytecode bytecode = static_cast<Bytecode>(value); 66 Bytecode bytecode = static_cast<Bytecode>(value);
65 DCHECK(bytecode <= Bytecode::kLast); 67 DCHECK(bytecode <= Bytecode::kLast);
66 return bytecode; 68 return bytecode;
67 } 69 }
68 70
69 71
70 // static 72 // static
73 int Bytecodes::Size(Bytecode bytecode) {
74 DCHECK(bytecode <= Bytecode::kLast);
75 switch (bytecode) {
76 #define CASE(Name, ...) \
77 case Bytecode::k##Name: \
78 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize;
79 BYTECODE_LIST(CASE)
80 #undef CASE
81 }
82 UNREACHABLE();
83 return 0;
84 }
85
86
87 // static
71 int Bytecodes::NumberOfOperands(Bytecode bytecode) { 88 int Bytecodes::NumberOfOperands(Bytecode bytecode) {
72 DCHECK(bytecode <= Bytecode::kLast); 89 DCHECK(bytecode <= Bytecode::kLast);
73 int count; 90 switch (bytecode) {
74 uint8_t row = ToByte(bytecode); 91 #define CASE(Name, ...) \
75 for (count = 0; count < kMaxOperands; count++) { 92 case Bytecode::k##Name: \
76 if (kBytecodeTable[row][count] == OperandType::kNone) { 93 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kOperandCount;
77 break; 94 BYTECODE_LIST(CASE)
78 } 95 #undef CASE
79 } 96 }
80 return count; 97 UNREACHABLE();
98 return 0;
81 } 99 }
82 100
83 101
84 // static 102 // static
85 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { 103 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
86 DCHECK(bytecode <= Bytecode::kLast && i < NumberOfOperands(bytecode)); 104 DCHECK(bytecode <= Bytecode::kLast);
87 return kBytecodeTable[ToByte(bytecode)][i]; 105 switch (bytecode) {
106 #define CASE(Name, ...) \
107 case Bytecode::k##Name: \
108 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandType(i);
109 BYTECODE_LIST(CASE)
110 #undef CASE
111 }
112 UNREACHABLE();
113 return OperandType::kNone;
88 } 114 }
89 115
90 116
91 // static 117 // static
92 int Bytecodes::Size(Bytecode bytecode) { 118 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i) {
93 return 1 + NumberOfOperands(bytecode); 119 DCHECK(bytecode <= Bytecode::kLast);
120 switch (bytecode) {
121 #define CASE(Name, ...) \
122 case Bytecode::k##Name: \
123 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandSize(i);
124 BYTECODE_LIST(CASE)
125 #undef CASE
126 }
127 UNREACHABLE();
128 return OperandSize::kNone;
94 } 129 }
95 130
96 131
97 // static 132 // static
98 int Bytecodes::MaximumNumberOfOperands() { return kMaxOperands; } 133 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i) {
134 DCHECK(bytecode <= Bytecode::kLast);
135 switch (bytecode) {
136 #define CASE(Name, ...) \
137 case Bytecode::k##Name: \
138 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandOffset(i);
139 BYTECODE_LIST(CASE)
140 #undef CASE
141 }
142 UNREACHABLE();
143 return 0;
144 }
99 145
100 146
101 // static 147 // static
102 int Bytecodes::MaximumSize() { return 1 + kMaxOperands; } 148 OperandSize Bytecodes::SizeOfOperand(OperandType operand_type) {
149 switch (operand_type) {
150 #define CASE(Name, Size) \
151 case OperandType::k##Name: \
152 return Size;
153 OPERAND_TYPE_LIST(CASE)
154 #undef CASE
155 }
156 UNREACHABLE();
157 return OperandSize::kNone;
158 }
103 159
104 160
105 // static 161 // static
106 bool Bytecodes::IsJump(Bytecode bytecode) { 162 bool Bytecodes::IsJump(Bytecode bytecode) {
107 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpIfTrue || 163 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpIfTrue ||
108 bytecode == Bytecode::kJumpIfFalse; 164 bytecode == Bytecode::kJumpIfFalse;
109 } 165 }
110 166
111 167
112 // static 168 // static
113 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { 169 bool Bytecodes::IsJumpConstant(Bytecode bytecode) {
114 return bytecode == Bytecode::kJumpConstant || 170 return bytecode == Bytecode::kJumpConstant ||
115 bytecode == Bytecode::kJumpIfTrueConstant || 171 bytecode == Bytecode::kJumpIfTrueConstant ||
116 bytecode == Bytecode::kJumpIfFalseConstant; 172 bytecode == Bytecode::kJumpIfFalseConstant;
117 } 173 }
118 174
119 175
120 // static 176 // static
177 uint16_t Bytecodes::ShortOperandFromBytes(const uint8_t* bytes) {
178 return *reinterpret_cast<const uint16_t*>(bytes);
179 }
180
181
182 // static
183 void Bytecodes::ShortOperandToBytes(uint16_t operand, uint8_t* bytes_out) {
184 *reinterpret_cast<uint16_t*>(bytes_out) = operand;
185 }
186
187
188 // static
121 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start, 189 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
122 int parameter_count) { 190 int parameter_count) {
123 Vector<char> buf = Vector<char>::New(50); 191 Vector<char> buf = Vector<char>::New(50);
124 192
125 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]); 193 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]);
126 int bytecode_size = Bytecodes::Size(bytecode); 194 int bytecode_size = Bytecodes::Size(bytecode);
127 195
128 for (int i = 0; i < bytecode_size; i++) { 196 for (int i = 0; i < bytecode_size; i++) {
129 SNPrintF(buf, "%02x ", bytecode_start[i]); 197 SNPrintF(buf, "%02x ", bytecode_start[i]);
130 os << buf.start(); 198 os << buf.start();
131 } 199 }
132 for (int i = bytecode_size; i < Bytecodes::MaximumSize(); i++) { 200 const int kBytecodeColumnSize = 6;
201 for (int i = bytecode_size; i < kBytecodeColumnSize; i++) {
133 os << " "; 202 os << " ";
134 } 203 }
135 204
136 os << bytecode << " "; 205 os << bytecode << " ";
137 206
138 const uint8_t* operands_start = bytecode_start + 1; 207 int number_of_operands = NumberOfOperands(bytecode);
139 int operands_size = bytecode_size - 1; 208 for (int i = 0; i < number_of_operands; i++) {
140 for (int i = 0; i < operands_size; i++) {
141 OperandType op_type = GetOperandType(bytecode, i); 209 OperandType op_type = GetOperandType(bytecode, i);
142 uint8_t operand = operands_start[i]; 210 const uint8_t* operand_start =
211 &bytecode_start[GetOperandOffset(bytecode, i)];
143 switch (op_type) { 212 switch (op_type) {
144 case interpreter::OperandType::kCount: 213 case interpreter::OperandType::kCount8:
145 os << "#" << static_cast<unsigned int>(operand); 214 os << "#" << static_cast<unsigned int>(*operand_start);
146 break; 215 break;
147 case interpreter::OperandType::kIdx: 216 case interpreter::OperandType::kIdx8:
148 os << "[" << static_cast<unsigned int>(operand) << "]"; 217 os << "[" << static_cast<unsigned int>(*operand_start) << "]";
149 break; 218 break;
219 case interpreter::OperandType::kIdx16: {
220 os << "[" << Bytecodes::ShortOperandFromBytes(operand_start) << "]";
221 break;
222 }
150 case interpreter::OperandType::kImm8: 223 case interpreter::OperandType::kImm8:
151 os << "#" << static_cast<int>(static_cast<int8_t>(operand)); 224 os << "#" << static_cast<int>(static_cast<int8_t>(*operand_start));
152 break; 225 break;
153 case interpreter::OperandType::kReg: { 226 case interpreter::OperandType::kReg8: {
154 Register reg = Register::FromOperand(operand); 227 Register reg = Register::FromOperand(*operand_start);
155 if (reg.is_parameter()) { 228 if (reg.is_parameter()) {
156 int parameter_index = reg.ToParameterIndex(parameter_count); 229 int parameter_index = reg.ToParameterIndex(parameter_count);
157 if (parameter_index == 0) { 230 if (parameter_index == 0) {
158 os << "<this>"; 231 os << "<this>";
159 } else { 232 } else {
160 os << "a" << parameter_index - 1; 233 os << "a" << parameter_index - 1;
161 } 234 }
162 } else { 235 } else {
163 os << "r" << reg.index(); 236 os << "r" << reg.index();
164 } 237 }
165 break; 238 break;
166 } 239 }
167 case interpreter::OperandType::kNone: 240 case interpreter::OperandType::kNone:
168 UNREACHABLE(); 241 UNREACHABLE();
169 break; 242 break;
170 } 243 }
171 if (i != operands_size - 1) { 244 if (i != number_of_operands - 1) {
172 os << ", "; 245 os << ", ";
173 } 246 }
174 } 247 }
175 return os; 248 return os;
176 } 249 }
177 250
178 251
179 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) { 252 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
180 return os << Bytecodes::ToString(bytecode); 253 return os << Bytecodes::ToString(bytecode);
181 } 254 }
182 255
183 256
184 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) { 257 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) {
185 return os << Bytecodes::OperandTypeToString(operand_type); 258 return os << Bytecodes::OperandTypeToString(operand_type);
186 } 259 }
187 260
188 261
262 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) {
263 return os << Bytecodes::OperandSizeToString(operand_size);
264 }
265
266
189 static const int kLastParamRegisterIndex = 267 static const int kLastParamRegisterIndex =
190 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; 268 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize;
191 269
192 270
193 // Registers occupy range 0-127 in 8-bit value leaving 128 unused values. 271 // Registers occupy range 0-127 in 8-bit value leaving 128 unused values.
194 // Parameter indices are biased with the negative value kLastParamRegisterIndex 272 // Parameter indices are biased with the negative value kLastParamRegisterIndex
195 // for ease of access in the interpreter. 273 // for ease of access in the interpreter.
196 static const int kMaxParameterIndex = 128 + kLastParamRegisterIndex; 274 static const int kMaxParameterIndex = 128 + kLastParamRegisterIndex;
197 275
198 276
(...skipping 20 matching lines...) Expand all
219 uint8_t Register::ToOperand() const { return static_cast<uint8_t>(-index_); } 297 uint8_t Register::ToOperand() const { return static_cast<uint8_t>(-index_); }
220 298
221 299
222 Register Register::FromOperand(uint8_t operand) { 300 Register Register::FromOperand(uint8_t operand) {
223 return Register(-static_cast<int8_t>(operand)); 301 return Register(-static_cast<int8_t>(operand));
224 } 302 }
225 303
226 } // namespace interpreter 304 } // namespace interpreter
227 } // namespace internal 305 } // namespace internal
228 } // namespace v8 306 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecodes.h ('k') | src/interpreter/interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698