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

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

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Additional test for debugger stepping and wider constant array builder test. Created 4 years, 9 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
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 #include "src/interpreter/bytecode-traits.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 namespace interpreter { 12 namespace interpreter {
13 13
14 14
15 // static 15 // static
16 const char* Bytecodes::ToString(Bytecode bytecode) { 16 const char* Bytecodes::ToString(Bytecode bytecode) {
17 switch (bytecode) { 17 switch (bytecode) {
18 #define CASE(Name, ...) \ 18 #define CASE(Name, ...) \
19 case Bytecode::k##Name: \ 19 case Bytecode::k##Name: \
20 return #Name; 20 return #Name;
21 BYTECODE_LIST(CASE) 21 BYTECODE_LIST(CASE)
22 #undef CASE 22 #undef CASE
23 } 23 }
24 UNREACHABLE(); 24 UNREACHABLE();
25 return ""; 25 return "";
26 } 26 }
27 27
28 // static
29 std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale) {
30 static const char kSeparator = '.';
31
32 std::string value(ToString(bytecode));
33 if (operand_scale > OperandScale::k1X) {
34 Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale);
35 std::string suffix = ToString(prefix_bytecode);
36 return value.append(1, kSeparator).append(suffix);
37 } else {
38 return value;
39 }
40 }
28 41
29 // static 42 // static
30 const char* Bytecodes::OperandTypeToString(OperandType operand_type) { 43 const char* Bytecodes::OperandTypeToString(OperandType operand_type) {
31 switch (operand_type) { 44 switch (operand_type) {
32 #define CASE(Name, _) \ 45 #define CASE(Name, _) \
33 case OperandType::k##Name: \ 46 case OperandType::k##Name: \
34 return #Name; 47 return #Name;
35 OPERAND_TYPE_LIST(CASE) 48 OPERAND_TYPE_LIST(CASE)
36 #undef CASE 49 #undef CASE
37 } 50 }
38 UNREACHABLE(); 51 UNREACHABLE();
39 return ""; 52 return "";
40 } 53 }
41 54
55 // static
56 const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) {
57 switch (operand_scale) {
58 case OperandScale::k1X:
59 return "1X";
60 case OperandScale::k2X:
61 return "2X";
62 case OperandScale::k4X:
63 return "4X";
64 case OperandScale::kInvalid:
65 UNREACHABLE();
66 }
67 return "";
68 }
42 69
43 // static 70 // static
44 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) { 71 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) {
45 switch (operand_size) { 72 switch (operand_size) {
46 case OperandSize::kNone: 73 case OperandSize::kNone:
47 return "None"; 74 return "None";
48 case OperandSize::kByte: 75 case OperandSize::kByte:
49 return "Byte"; 76 return "Byte";
50 case OperandSize::kShort: 77 case OperandSize::kShort:
51 return "Short"; 78 return "Short";
79 case OperandSize::kQuad:
80 return "Quad";
52 } 81 }
53 UNREACHABLE(); 82 UNREACHABLE();
54 return ""; 83 return "";
55 } 84 }
56 85
57 86
58 // static 87 // static
59 uint8_t Bytecodes::ToByte(Bytecode bytecode) { 88 uint8_t Bytecodes::ToByte(Bytecode bytecode) {
60 DCHECK(bytecode <= Bytecode::kLast); 89 DCHECK(bytecode <= Bytecode::kLast);
61 return static_cast<uint8_t>(bytecode); 90 return static_cast<uint8_t>(bytecode);
62 } 91 }
63 92
64 93
65 // static 94 // static
66 Bytecode Bytecodes::FromByte(uint8_t value) { 95 Bytecode Bytecodes::FromByte(uint8_t value) {
67 Bytecode bytecode = static_cast<Bytecode>(value); 96 Bytecode bytecode = static_cast<Bytecode>(value);
68 DCHECK(bytecode <= Bytecode::kLast); 97 DCHECK(bytecode <= Bytecode::kLast);
69 return bytecode; 98 return bytecode;
70 } 99 }
71 100
72 101
73 // static 102 // static
74 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) { 103 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
75 switch (Size(bytecode)) { 104 DCHECK(!IsDebugBreak(bytecode));
76 #define CASE(Name, ...) \ 105 if (bytecode == Bytecode::kWide) {
77 case BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize: \ 106 return Bytecode::kDebugBreakWide;
78 return Bytecode::k##Name;
79 DEBUG_BREAK_BYTECODE_LIST(CASE)
80 #undef CASE
81 default:
82 break;
83 } 107 }
108 if (bytecode == Bytecode::kExtraWide) {
109 return Bytecode::kDebugBreakExtraWide;
110 }
111 int bytecode_size = Size(bytecode, OperandScale::k1X);
112 #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name, ...) \
113 if (bytecode_size == Size(Bytecode::k##Name, OperandScale::k1X)) { \
114 return Bytecode::k##Name; \
115 }
116 DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
117 #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
84 UNREACHABLE(); 118 UNREACHABLE();
85 return static_cast<Bytecode>(-1); 119 return Bytecode::kIllegal;
86 } 120 }
87 121
88 // static 122 // static
89 int Bytecodes::Size(Bytecode bytecode) { 123 int Bytecodes::Size(Bytecode bytecode, OperandScale operand_scale) {
90 DCHECK(bytecode <= Bytecode::kLast); 124 int size = 1;
91 switch (bytecode) { 125 for (int i = 0; i < NumberOfOperands(bytecode); i++) {
92 #define CASE(Name, ...) \ 126 OperandSize operand_size = GetOperandSize(bytecode, i, operand_scale);
93 case Bytecode::k##Name: \ 127 int delta = static_cast<int>(operand_size);
rmcilroy 2016/03/17 17:30:50 Could you add a comment to OperandSize that we rel
oth 2016/03/21 09:16:54 Done. And OperandScale.
94 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize; 128 DCHECK(base::bits::IsPowerOfTwo32(static_cast<uint32_t>(delta)));
95 BYTECODE_LIST(CASE) 129 size += delta;
96 #undef CASE
97 } 130 }
98 UNREACHABLE(); 131 return size;
99 return 0;
100 } 132 }
101 133
102 134
103 // static 135 // static
104 int Bytecodes::NumberOfOperands(Bytecode bytecode) { 136 int Bytecodes::NumberOfOperands(Bytecode bytecode) {
105 DCHECK(bytecode <= Bytecode::kLast); 137 DCHECK(bytecode <= Bytecode::kLast);
106 switch (bytecode) { 138 switch (bytecode) {
107 #define CASE(Name, ...) \ 139 #define CASE(Name, ...) \
108 case Bytecode::k##Name: \ 140 case Bytecode::k##Name: \
109 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kOperandCount; 141 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kOperandCount;
(...skipping 14 matching lines...) Expand all
124 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \ 156 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
125 return Name##Trait::kRegisterOperandCount; 157 return Name##Trait::kRegisterOperandCount;
126 BYTECODE_LIST(CASE) 158 BYTECODE_LIST(CASE)
127 #undef CASE 159 #undef CASE
128 } 160 }
129 UNREACHABLE(); 161 UNREACHABLE();
130 return false; 162 return false;
131 } 163 }
132 164
133 // static 165 // static
166 Bytecode Bytecodes::OperandScaleToPrefixBytecode(OperandScale operand_scale) {
167 switch (operand_scale) {
168 case OperandScale::k4X:
169 return Bytecode::kExtraWide;
170 case OperandScale::k2X:
171 return Bytecode::kWide;
172 default:
173 UNREACHABLE();
174 return Bytecode::kIllegal;
175 }
176 }
177
178 // static
179 bool Bytecodes::OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) {
180 return operand_scale != OperandScale::k1X;
181 }
182
183 // static
184 OperandScale Bytecodes::PrefixBytecodeToOperandScale(Bytecode bytecode) {
185 switch (bytecode) {
186 case Bytecode::kExtraWide:
187 case Bytecode::kDebugBreakExtraWide:
188 return OperandScale::k4X;
189 case Bytecode::kWide:
190 case Bytecode::kDebugBreakWide:
191 return OperandScale::k2X;
192 default:
193 UNREACHABLE();
194 return OperandScale::k1X;
195 }
196 }
197
198 // static
134 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { 199 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
135 DCHECK(bytecode <= Bytecode::kLast); 200 DCHECK(bytecode <= Bytecode::kLast);
136 switch (bytecode) { 201 switch (bytecode) {
137 #define CASE(Name, ...) \ 202 #define CASE(Name, ...) \
138 case Bytecode::k##Name: \ 203 case Bytecode::k##Name: \
139 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandType(i); 204 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandType(i);
140 BYTECODE_LIST(CASE) 205 BYTECODE_LIST(CASE)
141 #undef CASE 206 #undef CASE
142 } 207 }
143 UNREACHABLE(); 208 UNREACHABLE();
144 return OperandType::kNone; 209 return OperandType::kNone;
145 } 210 }
146 211
212 namespace {
rmcilroy 2016/03/17 17:30:50 Could we do this magic in BytecodeTraits instead?
oth 2016/03/21 09:16:53 Done.
147 213
148 // static 214 template <bool>
149 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i) { 215 struct OperandScaler {
150 DCHECK(bytecode <= Bytecode::kLast); 216 static int Multiply(int size, int operand_scale) { return 0; }
151 switch (bytecode) { 217 };
152 #define CASE(Name, ...) \ 218
153 case Bytecode::k##Name: \ 219 template <>
154 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandSize(i); 220 struct OperandScaler<false> {
155 BYTECODE_LIST(CASE) 221 static int Multiply(int size, int operand_scale) { return size; }
222 };
223
224 template <>
225 struct OperandScaler<true> {
226 static int Multiply(int size, int operand_scale) {
227 return size * operand_scale;
228 }
229 };
230
231 static OperandSize ScaledOperandSize(OperandType operand_type,
232 OperandScale operand_scale) {
233 switch (operand_type) {
234 #define CASE(Name, TypeInfo) \
235 case OperandType::k##Name: { \
236 OperandSize base_size = OperandTypeInfoTraits<TypeInfo>::kUnscaledSize; \
237 int size = \
238 OperandScaler<OperandTypeInfoTraits<TypeInfo>::kIsScalable>::Multiply( \
239 static_cast<int>(base_size), static_cast<int>(operand_scale)); \
240 OperandSize operand_size = static_cast<OperandSize>(size); \
241 DCHECK(operand_size == OperandSize::kByte || \
242 operand_size == OperandSize::kShort || \
243 operand_size == OperandSize::kQuad); \
244 return operand_size; \
245 }
246 OPERAND_TYPE_LIST(CASE)
156 #undef CASE 247 #undef CASE
157 } 248 }
158 UNREACHABLE(); 249 UNREACHABLE();
159 return OperandSize::kNone; 250 return OperandSize::kNone;
160 } 251 }
252 } // namespace
161 253
254 // static
255 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i,
256 OperandScale operand_scale) {
257 OperandType op_type = GetOperandType(bytecode, i);
258 return static_cast<OperandSize>(ScaledOperandSize(op_type, operand_scale));
259 }
162 260
163 // static 261 // static
164 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) { 262 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) {
165 DCHECK(bytecode <= Bytecode::kLast); 263 DCHECK(bytecode <= Bytecode::kLast);
166 switch (bytecode) { 264 switch (bytecode) {
167 #define CASE(Name, ...) \ 265 #define CASE(Name, ...) \
168 case Bytecode::k##Name: \ 266 case Bytecode::k##Name: \
169 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \ 267 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
170 return Name##Trait::kRegisterOperandBitmap; 268 return Name##Trait::kRegisterOperandBitmap;
171 BYTECODE_LIST(CASE) 269 BYTECODE_LIST(CASE)
172 #undef CASE 270 #undef CASE
173 } 271 }
174 UNREACHABLE(); 272 UNREACHABLE();
175 return false; 273 return false;
176 } 274 }
177 275
178 // static 276 // static
179 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i) { 277 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
180 DCHECK(bytecode <= Bytecode::kLast); 278 OperandScale operand_scale) {
181 switch (bytecode) { 279 int offset = 1;
182 #define CASE(Name, ...) \ 280 for (int operand_index = 0; operand_index < i; ++operand_index) {
rmcilroy 2016/03/17 17:30:50 Could you add a TODO to calculate this at compile
oth 2016/03/21 09:16:53 Done.
183 case Bytecode::k##Name: \ 281 OperandSize operand_size =
184 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandOffset(i); 282 GetOperandSize(bytecode, operand_index, operand_scale);
185 BYTECODE_LIST(CASE) 283 offset += static_cast<int>(operand_size);
186 #undef CASE
187 } 284 }
188 UNREACHABLE(); 285 return offset;
189 return 0;
190 } 286 }
191 287
192
193 // static 288 // static
194 OperandSize Bytecodes::SizeOfOperand(OperandType operand_type) { 289 OperandSize Bytecodes::SizeOfOperand(OperandType operand_type,
195 switch (operand_type) { 290 OperandScale operand_scale) {
196 #define CASE(Name, Size) \ 291 return static_cast<OperandSize>(
197 case OperandType::k##Name: \ 292 ScaledOperandSize(operand_type, operand_scale));
198 return Size;
199 OPERAND_TYPE_LIST(CASE)
200 #undef CASE
201 }
202 UNREACHABLE();
203 return OperandSize::kNone;
204 } 293 }
205 294
206
207 // static 295 // static
208 bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) { 296 bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) {
209 return bytecode == Bytecode::kJumpIfTrue || 297 return bytecode == Bytecode::kJumpIfTrue ||
210 bytecode == Bytecode::kJumpIfFalse || 298 bytecode == Bytecode::kJumpIfFalse ||
211 bytecode == Bytecode::kJumpIfToBooleanTrue || 299 bytecode == Bytecode::kJumpIfToBooleanTrue ||
212 bytecode == Bytecode::kJumpIfToBooleanFalse || 300 bytecode == Bytecode::kJumpIfToBooleanFalse ||
213 bytecode == Bytecode::kJumpIfNotHole || 301 bytecode == Bytecode::kJumpIfNotHole ||
214 bytecode == Bytecode::kJumpIfNull || 302 bytecode == Bytecode::kJumpIfNull ||
215 bytecode == Bytecode::kJumpIfUndefined; 303 bytecode == Bytecode::kJumpIfUndefined;
216 } 304 }
217 305
218 306
219 // static 307 // static
220 bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) { 308 bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) {
221 return bytecode == Bytecode::kJumpIfTrueConstant || 309 return bytecode == Bytecode::kJumpIfTrueConstant ||
222 bytecode == Bytecode::kJumpIfFalseConstant || 310 bytecode == Bytecode::kJumpIfFalseConstant ||
223 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || 311 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
224 bytecode == Bytecode::kJumpIfToBooleanFalseConstant || 312 bytecode == Bytecode::kJumpIfToBooleanFalseConstant ||
225 bytecode == Bytecode::kJumpIfNotHoleConstant || 313 bytecode == Bytecode::kJumpIfNotHoleConstant ||
226 bytecode == Bytecode::kJumpIfNullConstant || 314 bytecode == Bytecode::kJumpIfNullConstant ||
227 bytecode == Bytecode::kJumpIfUndefinedConstant; 315 bytecode == Bytecode::kJumpIfUndefinedConstant;
228 } 316 }
229 317
230
231 // static
232 bool Bytecodes::IsConditionalJumpConstantWide(Bytecode bytecode) {
233 return bytecode == Bytecode::kJumpIfTrueConstantWide ||
234 bytecode == Bytecode::kJumpIfFalseConstantWide ||
235 bytecode == Bytecode::kJumpIfToBooleanTrueConstantWide ||
236 bytecode == Bytecode::kJumpIfToBooleanFalseConstantWide ||
237 bytecode == Bytecode::kJumpIfNotHoleConstantWide ||
238 bytecode == Bytecode::kJumpIfNullConstantWide ||
239 bytecode == Bytecode::kJumpIfUndefinedConstantWide;
240 }
241
242
243 // static 318 // static
244 bool Bytecodes::IsConditionalJump(Bytecode bytecode) { 319 bool Bytecodes::IsConditionalJump(Bytecode bytecode) {
245 return IsConditionalJumpImmediate(bytecode) || 320 return IsConditionalJumpImmediate(bytecode) ||
246 IsConditionalJumpConstant(bytecode) || 321 IsConditionalJumpConstant(bytecode);
247 IsConditionalJumpConstantWide(bytecode);
248 } 322 }
249 323
250 324
251 // static 325 // static
252 bool Bytecodes::IsJumpImmediate(Bytecode bytecode) { 326 bool Bytecodes::IsJumpImmediate(Bytecode bytecode) {
253 return bytecode == Bytecode::kJump || IsConditionalJumpImmediate(bytecode); 327 return bytecode == Bytecode::kJump || IsConditionalJumpImmediate(bytecode);
254 } 328 }
255 329
256 330
257 // static 331 // static
258 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { 332 bool Bytecodes::IsJumpConstant(Bytecode bytecode) {
259 return bytecode == Bytecode::kJumpConstant || 333 return bytecode == Bytecode::kJumpConstant ||
260 IsConditionalJumpConstant(bytecode); 334 IsConditionalJumpConstant(bytecode);
261 } 335 }
262 336
263
264 // static
265 bool Bytecodes::IsJumpConstantWide(Bytecode bytecode) {
266 return bytecode == Bytecode::kJumpConstantWide ||
267 IsConditionalJumpConstantWide(bytecode);
268 }
269
270
271 // static 337 // static
272 bool Bytecodes::IsJump(Bytecode bytecode) { 338 bool Bytecodes::IsJump(Bytecode bytecode) {
273 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode) || 339 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
274 IsJumpConstantWide(bytecode);
275 } 340 }
276 341
277 342
278 // static 343 // static
279 bool Bytecodes::IsCallOrNew(Bytecode bytecode) { 344 bool Bytecodes::IsCallOrNew(Bytecode bytecode) {
280 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || 345 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall ||
281 bytecode == Bytecode::kNew || bytecode == Bytecode::kCallWide || 346 bytecode == Bytecode::kNew;
282 bytecode == Bytecode::kTailCallWide || bytecode == Bytecode::kNewWide;
283 } 347 }
284 348
285 // static 349 // static
286 bool Bytecodes::IsCallRuntime(Bytecode bytecode) { 350 bool Bytecodes::IsCallRuntime(Bytecode bytecode) {
287 return bytecode == Bytecode::kCallRuntime || 351 return bytecode == Bytecode::kCallRuntime ||
288 bytecode == Bytecode::kCallRuntimeWide || 352 bytecode == Bytecode::kCallRuntimeForPair;
289 bytecode == Bytecode::kCallRuntimeForPair ||
290 bytecode == Bytecode::kCallRuntimeForPairWide;
291 } 353 }
292 354
293 // static 355 // static
294 bool Bytecodes::IsDebugBreak(Bytecode bytecode) { 356 bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
295 switch (bytecode) { 357 switch (bytecode) {
296 #define CASE(Name, ...) case Bytecode::k##Name: 358 #define CASE(Name, ...) case Bytecode::k##Name:
297 DEBUG_BREAK_BYTECODE_LIST(CASE); 359 DEBUG_BREAK_BYTECODE_LIST(CASE);
298 #undef CASE 360 #undef CASE
299 return true; 361 return true;
300 default: 362 default:
301 break; 363 break;
302 } 364 }
303 return false; 365 return false;
304 } 366 }
305 367
306 // static 368 // static
369 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
370 switch (bytecode) {
371 #define CASE(Name, ...) \
372 case Bytecode::k##Name: \
373 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
374 return Name##Trait::IsScalable();
375 BYTECODE_LIST(CASE)
376 #undef CASE
377 }
378 UNREACHABLE();
379 return false;
380 }
381
382 // static
383 bool Bytecodes::IsPrefixScalingBytecode(Bytecode bytecode) {
384 switch (bytecode) {
385 case Bytecode::kExtraWide:
386 case Bytecode::kDebugBreakExtraWide:
387 case Bytecode::kWide:
388 case Bytecode::kDebugBreakWide:
389 return true;
390 default:
391 return false;
392 }
393 }
394
395 // static
307 bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) { 396 bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) {
308 return bytecode == Bytecode::kReturn || IsJump(bytecode); 397 return bytecode == Bytecode::kReturn || IsJump(bytecode);
309 } 398 }
310 399
311 // static 400 // static
312 bool Bytecodes::IsIndexOperandType(OperandType operand_type) { 401 bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) {
313 return operand_type == OperandType::kIdx8 || 402 return operand_type == OperandType::kMaybeReg;
314 operand_type == OperandType::kIdx16;
315 } 403 }
316 404
317 // static 405 // static
318 bool Bytecodes::IsImmediateOperandType(OperandType operand_type) {
319 return operand_type == OperandType::kImm8;
320 }
321
322 // static
323 bool Bytecodes::IsRegisterCountOperandType(OperandType operand_type) {
324 return (operand_type == OperandType::kRegCount8 ||
325 operand_type == OperandType::kRegCount16);
326 }
327
328 // static
329 bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) {
330 return (operand_type == OperandType::kMaybeReg8 ||
331 operand_type == OperandType::kMaybeReg16);
332 }
333
334 // static
335 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) { 406 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
336 switch (operand_type) { 407 switch (operand_type) {
337 #define CASE(Name, _) \ 408 #define CASE(Name, _) \
338 case OperandType::k##Name: \ 409 case OperandType::k##Name: \
339 return true; 410 return true;
340 REGISTER_OPERAND_TYPE_LIST(CASE) 411 REGISTER_OPERAND_TYPE_LIST(CASE)
341 #undef CASE 412 #undef CASE
342 #define CASE(Name, _) \ 413 #define CASE(Name, _) \
343 case OperandType::k##Name: \ 414 case OperandType::k##Name: \
344 break; 415 break;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 #define CASE(Name, _) \ 448 #define CASE(Name, _) \
378 case OperandType::k##Name: \ 449 case OperandType::k##Name: \
379 break; 450 break;
380 NON_REGISTER_OPERAND_TYPE_LIST(CASE) 451 NON_REGISTER_OPERAND_TYPE_LIST(CASE)
381 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) 452 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
382 #undef CASE 453 #undef CASE
383 } 454 }
384 return false; 455 return false;
385 } 456 }
386 457
458 // static
459 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
460 switch (operand_type) {
461 #define CASE(Name, _) \
462 case OperandType::k##Name: \
463 return OperandTraits<OperandType::k##Name>::TypeInfo::kIsUnsigned;
464 OPERAND_TYPE_LIST(CASE)
465 #undef CASE
466 }
467 UNREACHABLE();
468 return false;
469 }
470
471 // static
472 OperandScale Bytecodes::NextOperandScale(OperandScale operand_scale) {
473 DCHECK(operand_scale >= OperandScale::k1X &&
474 operand_scale <= OperandScale::kMaxValid);
475 return static_cast<OperandScale>(2 * static_cast<int>(operand_scale));
rmcilroy 2016/03/17 17:30:50 Also please add a comment in OperandScale that we
oth 2016/03/21 09:16:53 Done.
476 }
477
387 namespace { 478 namespace {
479 static uint32_t DecodeUnsignedOperand(const uint8_t* operand_start,
480 OperandType operand_type,
481 OperandScale operand_scale) {
482 DCHECK(Bytecodes::IsUnsignedOperandType(operand_type));
483 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
484 case OperandSize::kByte:
485 return *operand_start;
486 case OperandSize::kShort:
487 return ReadUnalignedUInt16(operand_start);
488 case OperandSize::kQuad:
489 return ReadUnalignedUInt32(operand_start);
490 case OperandSize::kNone:
491 UNREACHABLE();
492 }
493 return 0;
494 }
495
496 static int32_t DecodeSignedOperand(const uint8_t* operand_start,
497 OperandType operand_type,
498 OperandScale operand_scale) {
499 DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type));
500 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
501 case OperandSize::kByte:
502 return static_cast<int8_t>(*operand_start);
503 case OperandSize::kShort:
504 return static_cast<int16_t>(ReadUnalignedUInt16(operand_start));
505 case OperandSize::kQuad:
506 return static_cast<int32_t>(ReadUnalignedUInt32(operand_start));
507 case OperandSize::kNone:
508 UNREACHABLE();
509 }
510 return 0;
511 }
512
388 static Register DecodeRegister(const uint8_t* operand_start, 513 static Register DecodeRegister(const uint8_t* operand_start,
389 OperandType operand_type) { 514 OperandType operand_type,
390 switch (Bytecodes::SizeOfOperand(operand_type)) { 515 OperandScale operand_scale) {
391 case OperandSize::kByte: 516 DCHECK(Bytecodes::IsRegisterOperandType(operand_type));
392 return Register::FromOperand(*operand_start); 517 int32_t operand =
393 case OperandSize::kShort: 518 DecodeSignedOperand(operand_start, operand_type, operand_scale);
394 return Register::FromWideOperand(ReadUnalignedUInt16(operand_start)); 519 return Register::FromOperand(operand);
395 case OperandSize::kNone: {
396 UNREACHABLE();
397 }
398 }
399 return Register();
400 } 520 }
401 } // namespace 521 } // namespace
402 522
403 523
404 // static 524 // static
405 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start, 525 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
406 int parameter_count) { 526 int parameter_count) {
407 Vector<char> buf = Vector<char>::New(50); 527 Vector<char> buf = Vector<char>::New(50);
408 528
409 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]); 529 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]);
410 int bytecode_size = Bytecodes::Size(bytecode); 530 int prefix_offset = 0;
411 531 OperandScale operand_scale = OperandScale::k1X;
412 for (int i = 0; i < bytecode_size; i++) { 532 if (IsPrefixScalingBytecode(bytecode)) {
533 prefix_offset = 1;
534 bytecode = Bytecodes::FromByte(bytecode_start[1]);
535 }
536 int bytecode_size = Bytecodes::Size(bytecode, operand_scale);
537 for (int i = 0; i < prefix_offset + bytecode_size; i++) {
413 SNPrintF(buf, "%02x ", bytecode_start[i]); 538 SNPrintF(buf, "%02x ", bytecode_start[i]);
414 os << buf.start(); 539 os << buf.start();
415 } 540 }
416 const int kBytecodeColumnSize = 6; 541 const int kBytecodeColumnSize = 6;
417 for (int i = bytecode_size; i < kBytecodeColumnSize; i++) { 542 for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) {
418 os << " "; 543 os << " ";
419 } 544 }
420 545
421 os << bytecode << " "; 546 os << Bytecodes::ToString(bytecode, operand_scale) << " ";
422 547
423 // Operands for the debug break are from the original instruction. 548 // Operands for the debug break are from the original instruction.
424 if (IsDebugBreak(bytecode)) return os; 549 if (IsDebugBreak(bytecode)) return os;
425 550
426 int number_of_operands = NumberOfOperands(bytecode); 551 int number_of_operands = NumberOfOperands(bytecode);
427 int range = 0; 552 int range = 0;
428 for (int i = 0; i < number_of_operands; i++) { 553 for (int i = 0; i < number_of_operands; i++) {
429 OperandType op_type = GetOperandType(bytecode, i); 554 OperandType op_type = GetOperandType(bytecode, i);
430 const uint8_t* operand_start = 555 const uint8_t* operand_start =
431 &bytecode_start[GetOperandOffset(bytecode, i)]; 556 &bytecode_start[prefix_offset +
557 GetOperandOffset(bytecode, i, operand_scale)];
432 switch (op_type) { 558 switch (op_type) {
433 case interpreter::OperandType::kRegCount8: 559 case interpreter::OperandType::kRegCount:
434 os << "#" << static_cast<unsigned int>(*operand_start); 560 os << "#"
561 << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
435 break; 562 break;
436 case interpreter::OperandType::kRegCount16: 563 case interpreter::OperandType::kIdx:
437 os << '#' << ReadUnalignedUInt16(operand_start); 564 case interpreter::OperandType::kRuntimeId:
565 os << "["
566 << DecodeUnsignedOperand(operand_start, op_type, operand_scale)
567 << "]";
438 break; 568 break;
439 case interpreter::OperandType::kIdx8: 569 case interpreter::OperandType::kImm:
440 os << "[" << static_cast<unsigned int>(*operand_start) << "]"; 570 os << "[" << DecodeSignedOperand(operand_start, op_type, operand_scale)
571 << "]";
441 break; 572 break;
442 case interpreter::OperandType::kIdx16: 573 case interpreter::OperandType::kFlag8:
443 os << "[" << ReadUnalignedUInt16(operand_start) << "]"; 574 os << "#"
575 << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
444 break; 576 break;
445 case interpreter::OperandType::kImm8: 577 case interpreter::OperandType::kMaybeReg:
446 os << "#" << static_cast<int>(static_cast<int8_t>(*operand_start)); 578 case interpreter::OperandType::kReg:
447 break; 579 case interpreter::OperandType::kRegOut: {
448 case interpreter::OperandType::kMaybeReg8: 580 Register reg = DecodeRegister(operand_start, op_type, operand_scale);
449 case interpreter::OperandType::kMaybeReg16:
450 case interpreter::OperandType::kReg8:
451 case interpreter::OperandType::kReg16:
452 case interpreter::OperandType::kRegOut8:
453 case interpreter::OperandType::kRegOut16: {
454 Register reg = DecodeRegister(operand_start, op_type);
455 os << reg.ToString(parameter_count); 581 os << reg.ToString(parameter_count);
456 break; 582 break;
457 } 583 }
458 case interpreter::OperandType::kRegOutTriple8: 584 case interpreter::OperandType::kRegOutTriple:
459 case interpreter::OperandType::kRegOutTriple16:
460 range += 1; 585 range += 1;
461 case interpreter::OperandType::kRegOutPair8: 586 case interpreter::OperandType::kRegOutPair:
462 case interpreter::OperandType::kRegOutPair16: 587 case interpreter::OperandType::kRegPair: {
463 case interpreter::OperandType::kRegPair8:
464 case interpreter::OperandType::kRegPair16: {
465 range += 1; 588 range += 1;
466 Register first_reg = DecodeRegister(operand_start, op_type); 589 Register first_reg =
590 DecodeRegister(operand_start, op_type, operand_scale);
467 Register last_reg = Register(first_reg.index() + range); 591 Register last_reg = Register(first_reg.index() + range);
468 os << first_reg.ToString(parameter_count) << "-" 592 os << first_reg.ToString(parameter_count) << "-"
469 << last_reg.ToString(parameter_count); 593 << last_reg.ToString(parameter_count);
470 break; 594 break;
471 } 595 }
472 case interpreter::OperandType::kNone: 596 case interpreter::OperandType::kNone:
473 UNREACHABLE(); 597 UNREACHABLE();
474 break; 598 break;
475 } 599 }
476 if (i != number_of_operands - 1) { 600 if (i != number_of_operands - 1) {
477 os << ", "; 601 os << ", ";
478 } 602 }
479 } 603 }
480 return os; 604 return os;
481 } 605 }
482 606
483 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) { 607 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
484 return os << Bytecodes::ToString(bytecode); 608 return os << Bytecodes::ToString(bytecode);
485 } 609 }
486 610
611 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) {
612 return os << Bytecodes::OperandSizeToString(operand_size);
613 }
614
615 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale) {
616 return os << Bytecodes::OperandScaleToString(operand_scale);
617 }
487 618
488 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) { 619 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) {
489 return os << Bytecodes::OperandTypeToString(operand_type); 620 return os << Bytecodes::OperandTypeToString(operand_type);
490 } 621 }
491 622
492
493 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) {
494 return os << Bytecodes::OperandSizeToString(operand_size);
495 }
496
497 static const int kLastParamRegisterIndex = 623 static const int kLastParamRegisterIndex =
498 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; 624 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize;
499 static const int kFunctionClosureRegisterIndex = 625 static const int kFunctionClosureRegisterIndex =
500 -InterpreterFrameConstants::kFunctionFromRegisterPointer / kPointerSize; 626 -InterpreterFrameConstants::kFunctionFromRegisterPointer / kPointerSize;
501 static const int kCurrentContextRegisterIndex = 627 static const int kCurrentContextRegisterIndex =
502 -InterpreterFrameConstants::kContextFromRegisterPointer / kPointerSize; 628 -InterpreterFrameConstants::kContextFromRegisterPointer / kPointerSize;
503 static const int kNewTargetRegisterIndex = 629 static const int kNewTargetRegisterIndex =
504 -InterpreterFrameConstants::kNewTargetFromRegisterPointer / kPointerSize; 630 -InterpreterFrameConstants::kNewTargetFromRegisterPointer / kPointerSize;
505 631
506 // The register space is a signed 16-bit space. Register operands
507 // occupy range above 0. Parameter indices are biased with the
508 // negative value kLastParamRegisterIndex for ease of access in the
509 // interpreter.
510 static const int kMaxParameterIndex = kMaxInt16 + kLastParamRegisterIndex;
511 static const int kMaxRegisterIndex = -kMinInt16;
512 static const int kMaxReg8Index = -kMinInt8;
513 static const int kMinReg8Index = -kMaxInt8;
514 static const int kMaxReg16Index = -kMinInt16;
515 static const int kMinReg16Index = -kMaxInt16;
516
517 bool Register::is_byte_operand() const { 632 bool Register::is_byte_operand() const {
518 return index_ >= kMinReg8Index && index_ <= kMaxReg8Index; 633 return index_ >= -kMaxInt8 && index_ <= -kMinInt8;
519 } 634 }
520 635
521 bool Register::is_short_operand() const { 636 bool Register::is_short_operand() const {
522 return index_ >= kMinReg16Index && index_ <= kMaxReg16Index; 637 return index_ >= -kMaxInt16 && index_ <= -kMinInt16;
523 } 638 }
524 639
525 Register Register::FromParameterIndex(int index, int parameter_count) { 640 Register Register::FromParameterIndex(int index, int parameter_count) {
526 DCHECK_GE(index, 0); 641 DCHECK_GE(index, 0);
527 DCHECK_LT(index, parameter_count); 642 DCHECK_LT(index, parameter_count);
528 DCHECK_LE(parameter_count, kMaxParameterIndex + 1);
529 int register_index = kLastParamRegisterIndex - parameter_count + index + 1; 643 int register_index = kLastParamRegisterIndex - parameter_count + index + 1;
530 DCHECK_LT(register_index, 0); 644 DCHECK_LT(register_index, 0);
531 return Register(register_index); 645 return Register(register_index);
532 } 646 }
533 647
534 648
535 int Register::ToParameterIndex(int parameter_count) const { 649 int Register::ToParameterIndex(int parameter_count) const {
536 DCHECK(is_parameter()); 650 DCHECK(is_parameter());
537 return index() - kLastParamRegisterIndex + parameter_count - 1; 651 return index() - kLastParamRegisterIndex + parameter_count - 1;
538 } 652 }
(...skipping 19 matching lines...) Expand all
558 } 672 }
559 673
560 674
561 Register Register::new_target() { return Register(kNewTargetRegisterIndex); } 675 Register Register::new_target() { return Register(kNewTargetRegisterIndex); }
562 676
563 677
564 bool Register::is_new_target() const { 678 bool Register::is_new_target() const {
565 return index() == kNewTargetRegisterIndex; 679 return index() == kNewTargetRegisterIndex;
566 } 680 }
567 681
568 int Register::MaxParameterIndex() { return kMaxParameterIndex; }
569
570 int Register::MaxRegisterIndex() { return kMaxRegisterIndex; }
571
572 int Register::MaxRegisterIndexForByteOperand() { return kMaxReg8Index; }
573
574 uint8_t Register::ToOperand() const {
575 DCHECK(is_byte_operand());
576 return static_cast<uint8_t>(-index_);
577 }
578
579
580 Register Register::FromOperand(uint8_t operand) {
581 return Register(-static_cast<int8_t>(operand));
582 }
583
584
585 uint16_t Register::ToWideOperand() const {
586 DCHECK(is_short_operand());
587 return static_cast<uint16_t>(-index_);
588 }
589
590
591 Register Register::FromWideOperand(uint16_t operand) {
592 return Register(-static_cast<int16_t>(operand));
593 }
594
595
596 uint32_t Register::ToRawOperand() const {
597 return static_cast<uint32_t>(-index_);
598 }
599
600
601 Register Register::FromRawOperand(uint32_t operand) {
602 return Register(-static_cast<int32_t>(operand));
603 }
604
605
606 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3, 682 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3,
607 Register reg4, Register reg5) { 683 Register reg4, Register reg5) {
608 if (reg1.index() + 1 != reg2.index()) { 684 if (reg1.index() + 1 != reg2.index()) {
609 return false; 685 return false;
610 } 686 }
611 if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) { 687 if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) {
612 return false; 688 return false;
613 } 689 }
614 if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) { 690 if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) {
615 return false; 691 return false;
(...skipping 23 matching lines...) Expand all
639 } else { 715 } else {
640 std::ostringstream s; 716 std::ostringstream s;
641 s << "r" << index(); 717 s << "r" << index();
642 return s.str(); 718 return s.str();
643 } 719 }
644 } 720 }
645 721
646 } // namespace interpreter 722 } // namespace interpreter
647 } // namespace internal 723 } // namespace internal
648 } // namespace v8 724 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698