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 #ifndef V8_INTERPRETER_BYTECODES_H_ | 5 #ifndef V8_INTERPRETER_BYTECODES_H_ |
6 #define V8_INTERPRETER_BYTECODES_H_ | 6 #define V8_INTERPRETER_BYTECODES_H_ |
7 | 7 |
8 #include <cstdint> | 8 #include <cstdint> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 #include <string> | 10 #include <string> |
11 | 11 |
12 #include "src/globals.h" | |
13 #include "src/interpreter/bytecode-operands.h" | |
14 | |
15 // This interface and it's implementation are independent of the | 12 // This interface and it's implementation are independent of the |
16 // libv8_base library as they are used by the interpreter and the | 13 // libv8_base library as they are used by the interpreter and the |
17 // standalone mkpeephole table generator program. | 14 // standalone mkpeephole table generator program. |
18 | 15 |
19 namespace v8 { | 16 namespace v8 { |
20 namespace internal { | 17 namespace internal { |
21 namespace interpreter { | 18 namespace interpreter { |
22 | 19 |
| 20 #define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone) |
| 21 |
| 22 #define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \ |
| 23 V(MaybeReg, OperandTypeInfo::kScalableSignedByte) \ |
| 24 V(Reg, OperandTypeInfo::kScalableSignedByte) \ |
| 25 V(RegPair, OperandTypeInfo::kScalableSignedByte) |
| 26 |
| 27 #define REGISTER_OUTPUT_OPERAND_TYPE_LIST(V) \ |
| 28 V(RegOut, OperandTypeInfo::kScalableSignedByte) \ |
| 29 V(RegOutPair, OperandTypeInfo::kScalableSignedByte) \ |
| 30 V(RegOutTriple, OperandTypeInfo::kScalableSignedByte) |
| 31 |
| 32 #define SCALAR_OPERAND_TYPE_LIST(V) \ |
| 33 V(Flag8, OperandTypeInfo::kFixedUnsignedByte) \ |
| 34 V(IntrinsicId, OperandTypeInfo::kFixedUnsignedByte) \ |
| 35 V(Idx, OperandTypeInfo::kScalableUnsignedByte) \ |
| 36 V(UImm, OperandTypeInfo::kScalableUnsignedByte) \ |
| 37 V(Imm, OperandTypeInfo::kScalableSignedByte) \ |
| 38 V(RegCount, OperandTypeInfo::kScalableUnsignedByte) \ |
| 39 V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort) |
| 40 |
| 41 #define REGISTER_OPERAND_TYPE_LIST(V) \ |
| 42 REGISTER_INPUT_OPERAND_TYPE_LIST(V) \ |
| 43 REGISTER_OUTPUT_OPERAND_TYPE_LIST(V) |
| 44 |
| 45 #define NON_REGISTER_OPERAND_TYPE_LIST(V) \ |
| 46 INVALID_OPERAND_TYPE_LIST(V) \ |
| 47 SCALAR_OPERAND_TYPE_LIST(V) |
| 48 |
| 49 // The list of operand types used by bytecodes. |
| 50 #define OPERAND_TYPE_LIST(V) \ |
| 51 NON_REGISTER_OPERAND_TYPE_LIST(V) \ |
| 52 REGISTER_OPERAND_TYPE_LIST(V) |
| 53 |
| 54 // Define one debug break bytecode for each possible size of unscaled |
| 55 // bytecodes. Format is V(<bytecode>, <accumulator_use>, <operands>). |
| 56 #define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ |
| 57 V(DebugBreak0, AccumulatorUse::kRead) \ |
| 58 V(DebugBreak1, AccumulatorUse::kRead, OperandType::kReg) \ |
| 59 V(DebugBreak2, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg) \ |
| 60 V(DebugBreak3, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \ |
| 61 OperandType::kReg) \ |
| 62 V(DebugBreak4, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \ |
| 63 OperandType::kReg, OperandType::kReg) \ |
| 64 V(DebugBreak5, AccumulatorUse::kRead, OperandType::kRuntimeId, \ |
| 65 OperandType::kReg, OperandType::kReg) \ |
| 66 V(DebugBreak6, AccumulatorUse::kRead, OperandType::kRuntimeId, \ |
| 67 OperandType::kReg, OperandType::kReg, OperandType::kReg) |
| 68 |
| 69 // Define one debug break for each widening prefix. |
| 70 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \ |
| 71 V(DebugBreakWide, AccumulatorUse::kRead) \ |
| 72 V(DebugBreakExtraWide, AccumulatorUse::kRead) |
| 73 |
| 74 #define DEBUG_BREAK_BYTECODE_LIST(V) \ |
| 75 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ |
| 76 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) |
| 77 |
23 // The list of bytecodes which are interpreted by the interpreter. | 78 // The list of bytecodes which are interpreted by the interpreter. |
24 // Format is V(<bytecode>, <accumulator_use>, <operands>). | |
25 #define BYTECODE_LIST(V) \ | 79 #define BYTECODE_LIST(V) \ |
26 /* Extended width operands */ \ | 80 /* Extended width operands */ \ |
27 V(Wide, AccumulatorUse::kNone) \ | 81 V(Wide, AccumulatorUse::kNone) \ |
28 V(ExtraWide, AccumulatorUse::kNone) \ | 82 V(ExtraWide, AccumulatorUse::kNone) \ |
29 \ | 83 \ |
30 /* Loading the accumulator */ \ | 84 /* Loading the accumulator */ \ |
31 V(LdaZero, AccumulatorUse::kWrite) \ | 85 V(LdaZero, AccumulatorUse::kWrite) \ |
32 V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \ | 86 V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \ |
33 V(LdaUndefined, AccumulatorUse::kWrite) \ | 87 V(LdaUndefined, AccumulatorUse::kWrite) \ |
34 V(LdaNull, AccumulatorUse::kWrite) \ | 88 V(LdaNull, AccumulatorUse::kWrite) \ |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 V(Throw, AccumulatorUse::kRead) \ | 299 V(Throw, AccumulatorUse::kRead) \ |
246 V(ReThrow, AccumulatorUse::kRead) \ | 300 V(ReThrow, AccumulatorUse::kRead) \ |
247 V(Return, AccumulatorUse::kRead) \ | 301 V(Return, AccumulatorUse::kRead) \ |
248 \ | 302 \ |
249 /* Generators */ \ | 303 /* Generators */ \ |
250 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \ | 304 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \ |
251 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg) \ | 305 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg) \ |
252 \ | 306 \ |
253 /* Debugger */ \ | 307 /* Debugger */ \ |
254 V(Debugger, AccumulatorUse::kNone) \ | 308 V(Debugger, AccumulatorUse::kNone) \ |
255 \ | 309 DEBUG_BREAK_BYTECODE_LIST(V) \ |
256 /* Debug Breakpoints - one for each possible size of unscaled bytecodes */ \ | |
257 /* and one for each operand widening prefix bytecode */ \ | |
258 V(DebugBreak0, AccumulatorUse::kRead) \ | |
259 V(DebugBreak1, AccumulatorUse::kRead, OperandType::kReg) \ | |
260 V(DebugBreak2, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg) \ | |
261 V(DebugBreak3, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \ | |
262 OperandType::kReg) \ | |
263 V(DebugBreak4, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \ | |
264 OperandType::kReg, OperandType::kReg) \ | |
265 V(DebugBreak5, AccumulatorUse::kRead, OperandType::kRuntimeId, \ | |
266 OperandType::kReg, OperandType::kReg) \ | |
267 V(DebugBreak6, AccumulatorUse::kRead, OperandType::kRuntimeId, \ | |
268 OperandType::kReg, OperandType::kReg, OperandType::kReg) \ | |
269 V(DebugBreakWide, AccumulatorUse::kRead) \ | |
270 V(DebugBreakExtraWide, AccumulatorUse::kRead) \ | |
271 \ | 310 \ |
272 /* Illegal bytecode (terminates execution) */ \ | 311 /* Illegal bytecode (terminates execution) */ \ |
273 V(Illegal, AccumulatorUse::kNone) \ | 312 V(Illegal, AccumulatorUse::kNone) \ |
274 \ | 313 \ |
275 /* No operation (used to maintain source positions for peephole */ \ | 314 /* No operation (used to maintain source positions for peephole */ \ |
276 /* eliminated bytecodes). */ \ | 315 /* eliminated bytecodes). */ \ |
277 V(Nop, AccumulatorUse::kNone) | 316 V(Nop, AccumulatorUse::kNone) |
278 | 317 |
279 // List of debug break bytecodes. | 318 enum class AccumulatorUse : uint8_t { |
280 #define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ | 319 kNone = 0, |
281 V(DebugBreak0) \ | 320 kRead = 1 << 0, |
282 V(DebugBreak1) \ | 321 kWrite = 1 << 1, |
283 V(DebugBreak2) \ | 322 kReadWrite = kRead | kWrite |
284 V(DebugBreak3) \ | 323 }; |
285 V(DebugBreak4) \ | |
286 V(DebugBreak5) \ | |
287 V(DebugBreak6) | |
288 | 324 |
289 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \ | 325 inline AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) { |
290 V(DebugBreakWide) \ | 326 int result = static_cast<int>(lhs) & static_cast<int>(rhs); |
291 V(DebugBreakExtraWide) | 327 return static_cast<AccumulatorUse>(result); |
| 328 } |
292 | 329 |
293 #define DEBUG_BREAK_BYTECODE_LIST(V) \ | 330 inline AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) { |
294 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ | 331 int result = static_cast<int>(lhs) | static_cast<int>(rhs); |
295 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) | 332 return static_cast<AccumulatorUse>(result); |
| 333 } |
| 334 |
| 335 // Enumeration of scaling factors applicable to scalable operands. Code |
| 336 // relies on being able to cast values to integer scaling values. |
| 337 #define OPERAND_SCALE_LIST(V) \ |
| 338 V(Single, 1) \ |
| 339 V(Double, 2) \ |
| 340 V(Quadruple, 4) |
| 341 |
| 342 enum class OperandScale : uint8_t { |
| 343 #define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale, |
| 344 OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE) |
| 345 #undef DECLARE_OPERAND_SCALE |
| 346 kLast = kQuadruple |
| 347 }; |
| 348 |
| 349 // Enumeration of the size classes of operand types used by |
| 350 // bytecodes. Code relies on being able to cast values to integer |
| 351 // types to get the size in bytes. |
| 352 enum class OperandSize : uint8_t { |
| 353 kNone = 0, |
| 354 kByte = 1, |
| 355 kShort = 2, |
| 356 kQuad = 4, |
| 357 kLast = kQuad |
| 358 }; |
| 359 |
| 360 // Primitive operand info used that summarize properties of operands. |
| 361 // Columns are Name, IsScalable, IsUnsigned, UnscaledSize. |
| 362 #define OPERAND_TYPE_INFO_LIST(V) \ |
| 363 V(None, false, false, OperandSize::kNone) \ |
| 364 V(ScalableSignedByte, true, false, OperandSize::kByte) \ |
| 365 V(ScalableUnsignedByte, true, true, OperandSize::kByte) \ |
| 366 V(FixedUnsignedByte, false, true, OperandSize::kByte) \ |
| 367 V(FixedUnsignedShort, false, true, OperandSize::kShort) |
| 368 |
| 369 enum class OperandTypeInfo : uint8_t { |
| 370 #define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name, |
| 371 OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO) |
| 372 #undef DECLARE_OPERAND_TYPE_INFO |
| 373 }; |
| 374 |
| 375 // Enumeration of operand types used by bytecodes. |
| 376 enum class OperandType : uint8_t { |
| 377 #define DECLARE_OPERAND_TYPE(Name, _) k##Name, |
| 378 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE) |
| 379 #undef DECLARE_OPERAND_TYPE |
| 380 #define COUNT_OPERAND_TYPES(x, _) +1 |
| 381 // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will |
| 382 // evaluate to the same value as the last operand. |
| 383 kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES) |
| 384 #undef COUNT_OPERAND_TYPES |
| 385 }; |
296 | 386 |
297 // Enumeration of interpreter bytecodes. | 387 // Enumeration of interpreter bytecodes. |
298 enum class Bytecode : uint8_t { | 388 enum class Bytecode : uint8_t { |
299 #define DECLARE_BYTECODE(Name, ...) k##Name, | 389 #define DECLARE_BYTECODE(Name, ...) k##Name, |
300 BYTECODE_LIST(DECLARE_BYTECODE) | 390 BYTECODE_LIST(DECLARE_BYTECODE) |
301 #undef DECLARE_BYTECODE | 391 #undef DECLARE_BYTECODE |
302 #define COUNT_BYTECODE(x, ...) +1 | 392 #define COUNT_BYTECODE(x, ...) +1 |
303 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will | 393 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will |
304 // evaluate to the same value as the last real bytecode. | 394 // evaluate to the same value as the last real bytecode. |
305 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) | 395 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) |
306 #undef COUNT_BYTECODE | 396 #undef COUNT_BYTECODE |
307 }; | 397 }; |
308 | 398 |
309 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr. | |
310 // See crbug.com/603131. | |
311 #if V8_CC_MSVC | |
312 #define CONSTEXPR const | |
313 #else | |
314 #define CONSTEXPR constexpr | |
315 #endif | |
316 | |
317 class Bytecodes final { | 399 class Bytecodes final { |
318 public: | 400 public: |
319 // The maximum number of operands a bytecode may have. | 401 // The maximum number of operands a bytecode may have. |
320 static const int kMaxOperands = 4; | 402 static const int kMaxOperands = 4; |
321 | 403 |
322 // Returns string representation of |bytecode|. | 404 // Returns string representation of |bytecode|. |
323 static const char* ToString(Bytecode bytecode); | 405 static const char* ToString(Bytecode bytecode); |
324 | 406 |
325 // Returns string representation of |bytecode|. | 407 // Returns string representation of |bytecode|. |
326 static std::string ToString(Bytecode bytecode, OperandScale operand_scale); | 408 static std::string ToString(Bytecode bytecode, OperandScale operand_scale); |
327 | 409 |
| 410 // Returns string representation of |accumulator_use|. |
| 411 static const char* AccumulatorUseToString(AccumulatorUse accumulator_use); |
| 412 |
| 413 // Returns string representation of |operand_type|. |
| 414 static const char* OperandTypeToString(OperandType operand_type); |
| 415 |
| 416 // Returns string representation of |operand_scale|. |
| 417 static const char* OperandScaleToString(OperandScale operand_scale); |
| 418 |
| 419 // Returns string representation of |operand_size|. |
| 420 static const char* OperandSizeToString(OperandSize operand_size); |
| 421 |
328 // Returns byte value of bytecode. | 422 // Returns byte value of bytecode. |
329 static uint8_t ToByte(Bytecode bytecode) { | 423 static uint8_t ToByte(Bytecode bytecode); |
330 DCHECK_LE(bytecode, Bytecode::kLast); | |
331 return static_cast<uint8_t>(bytecode); | |
332 } | |
333 | 424 |
334 // Returns bytecode for |value|. | 425 // Returns bytecode for |value|. |
335 static Bytecode FromByte(uint8_t value) { | 426 static Bytecode FromByte(uint8_t value); |
336 Bytecode bytecode = static_cast<Bytecode>(value); | 427 |
337 DCHECK(bytecode <= Bytecode::kLast); | 428 // Returns the number of operands expected by |bytecode|. |
338 return bytecode; | 429 static int NumberOfOperands(Bytecode bytecode); |
339 } | 430 |
| 431 // Returns the number of register operands expected by |bytecode|. |
| 432 static int NumberOfRegisterOperands(Bytecode bytecode); |
340 | 433 |
341 // Returns the prefix bytecode representing an operand scale to be | 434 // Returns the prefix bytecode representing an operand scale to be |
342 // applied to a a bytecode. | 435 // applied to a a bytecode. |
343 static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale) { | 436 static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale); |
344 switch (operand_scale) { | |
345 case OperandScale::kQuadruple: | |
346 return Bytecode::kExtraWide; | |
347 case OperandScale::kDouble: | |
348 return Bytecode::kWide; | |
349 default: | |
350 UNREACHABLE(); | |
351 return Bytecode::kIllegal; | |
352 } | |
353 } | |
354 | 437 |
355 // Returns true if the operand scale requires a prefix bytecode. | 438 // Returns true if the operand scale requires a prefix bytecode. |
356 static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) { | 439 static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale); |
357 return operand_scale != OperandScale::kSingle; | |
358 } | |
359 | 440 |
360 // Returns the scaling applied to scalable operands if bytecode is | 441 // Returns the scaling applied to scalable operands if bytecode is |
361 // is a scaling prefix. | 442 // is a scaling prefix. |
362 static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode) { | 443 static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode); |
363 switch (bytecode) { | |
364 case Bytecode::kExtraWide: | |
365 case Bytecode::kDebugBreakExtraWide: | |
366 return OperandScale::kQuadruple; | |
367 case Bytecode::kWide: | |
368 case Bytecode::kDebugBreakWide: | |
369 return OperandScale::kDouble; | |
370 default: | |
371 UNREACHABLE(); | |
372 return OperandScale::kSingle; | |
373 } | |
374 } | |
375 | 444 |
376 // Returns how accumulator is used by |bytecode|. | 445 // Returns how accumulator is used by |bytecode|. |
377 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) { | 446 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode); |
378 DCHECK(bytecode <= Bytecode::kLast); | |
379 return kAccumulatorUse[static_cast<size_t>(bytecode)]; | |
380 } | |
381 | 447 |
382 // Returns true if |bytecode| reads the accumulator. | 448 // Returns true if |bytecode| reads the accumulator. |
383 static bool ReadsAccumulator(Bytecode bytecode) { | 449 static bool ReadsAccumulator(Bytecode bytecode); |
384 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kRead) == | |
385 AccumulatorUse::kRead; | |
386 } | |
387 | 450 |
388 // Returns true if |bytecode| writes the accumulator. | 451 // Returns true if |bytecode| writes the accumulator. |
389 static bool WritesAccumulator(Bytecode bytecode) { | 452 static bool WritesAccumulator(Bytecode bytecode); |
390 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) == | |
391 AccumulatorUse::kWrite; | |
392 } | |
393 | 453 |
394 // Return true if |bytecode| writes the accumulator with a boolean value. | 454 // Return true if |bytecode| writes the accumulator with a boolean value. |
395 static bool WritesBooleanToAccumulator(Bytecode bytecode) { | 455 static bool WritesBooleanToAccumulator(Bytecode bytecode); |
396 switch (bytecode) { | |
397 case Bytecode::kLdaTrue: | |
398 case Bytecode::kLdaFalse: | |
399 case Bytecode::kToBooleanLogicalNot: | |
400 case Bytecode::kLogicalNot: | |
401 case Bytecode::kTestEqual: | |
402 case Bytecode::kTestNotEqual: | |
403 case Bytecode::kTestEqualStrict: | |
404 case Bytecode::kTestLessThan: | |
405 case Bytecode::kTestLessThanOrEqual: | |
406 case Bytecode::kTestGreaterThan: | |
407 case Bytecode::kTestGreaterThanOrEqual: | |
408 case Bytecode::kTestInstanceOf: | |
409 case Bytecode::kTestIn: | |
410 case Bytecode::kForInContinue: | |
411 return true; | |
412 default: | |
413 return false; | |
414 } | |
415 } | |
416 | 456 |
417 // Return true if |bytecode| is an accumulator load without effects, | 457 // Return true if |bytecode| is an accumulator load without effects, |
418 // e.g. LdaConstant, LdaTrue, Ldar. | 458 // e.g. LdaConstant, LdaTrue, Ldar. |
419 static CONSTEXPR bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode) { | 459 static bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode); |
420 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kLdaZero || | |
421 bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaNull || | |
422 bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse || | |
423 bytecode == Bytecode::kLdaUndefined || | |
424 bytecode == Bytecode::kLdaTheHole || | |
425 bytecode == Bytecode::kLdaConstant; | |
426 } | |
427 | |
428 // Return true if |bytecode| is a register load without effects, | |
429 // e.g. Mov, Star, LdrUndefined. | |
430 static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) { | |
431 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext || | |
432 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar || | |
433 bytecode == Bytecode::kLdrUndefined; | |
434 } | |
435 | |
436 // Returns true if the bytecode is a conditional jump taking | |
437 // an immediate byte operand (OperandType::kImm). | |
438 static CONSTEXPR bool IsConditionalJumpImmediate(Bytecode bytecode) { | |
439 return bytecode == Bytecode::kJumpIfTrue || | |
440 bytecode == Bytecode::kJumpIfFalse || | |
441 bytecode == Bytecode::kJumpIfToBooleanTrue || | |
442 bytecode == Bytecode::kJumpIfToBooleanFalse || | |
443 bytecode == Bytecode::kJumpIfNotHole || | |
444 bytecode == Bytecode::kJumpIfNull || | |
445 bytecode == Bytecode::kJumpIfUndefined; | |
446 } | |
447 | |
448 // Returns true if the bytecode is a conditional jump taking | |
449 // a constant pool entry (OperandType::kIdx). | |
450 static CONSTEXPR bool IsConditionalJumpConstant(Bytecode bytecode) { | |
451 return bytecode == Bytecode::kJumpIfTrueConstant || | |
452 bytecode == Bytecode::kJumpIfFalseConstant || | |
453 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || | |
454 bytecode == Bytecode::kJumpIfToBooleanFalseConstant || | |
455 bytecode == Bytecode::kJumpIfNotHoleConstant || | |
456 bytecode == Bytecode::kJumpIfNullConstant || | |
457 bytecode == Bytecode::kJumpIfUndefinedConstant; | |
458 } | |
459 | |
460 // Returns true if the bytecode is a conditional jump taking | |
461 // any kind of operand. | |
462 static CONSTEXPR bool IsConditionalJump(Bytecode bytecode) { | |
463 return IsConditionalJumpImmediate(bytecode) || | |
464 IsConditionalJumpConstant(bytecode); | |
465 } | |
466 | |
467 // Returns true if the bytecode is a jump or a conditional jump taking | |
468 // an immediate byte operand (OperandType::kImm). | |
469 static CONSTEXPR bool IsJumpImmediate(Bytecode bytecode) { | |
470 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop || | |
471 IsConditionalJumpImmediate(bytecode); | |
472 } | |
473 | |
474 // Returns true if the bytecode is a jump or conditional jump taking a | |
475 // constant pool entry (OperandType::kIdx). | |
476 static CONSTEXPR bool IsJumpConstant(Bytecode bytecode) { | |
477 return bytecode == Bytecode::kJumpConstant || | |
478 IsConditionalJumpConstant(bytecode); | |
479 } | |
480 | |
481 // Returns true if the bytecode is a jump that internally coerces the | |
482 // accumulator to a boolean. | |
483 static CONSTEXPR bool IsJumpIfToBoolean(Bytecode bytecode) { | |
484 return bytecode == Bytecode::kJumpIfToBooleanTrue || | |
485 bytecode == Bytecode::kJumpIfToBooleanFalse || | |
486 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || | |
487 bytecode == Bytecode::kJumpIfToBooleanFalseConstant; | |
488 } | |
489 | |
490 // Returns true if the bytecode is a jump or conditional jump taking | |
491 // any kind of operand. | |
492 static CONSTEXPR bool IsJump(Bytecode bytecode) { | |
493 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); | |
494 } | |
495 | |
496 // Returns true if the bytecode is a conditional jump, a jump, or a return. | |
497 static CONSTEXPR bool IsJumpOrReturn(Bytecode bytecode) { | |
498 return bytecode == Bytecode::kReturn || IsJump(bytecode); | |
499 } | |
500 | 460 |
501 // Return true if |bytecode| is a jump without effects, | 461 // Return true if |bytecode| is a jump without effects, |
502 // e.g. any jump excluding those that include type coercion like | 462 // e.g. any jump excluding those that include type coercion like |
503 // JumpIfTrueToBoolean. | 463 // JumpIfTrueToBoolean. |
504 static CONSTEXPR bool IsJumpWithoutEffects(Bytecode bytecode) { | 464 static bool IsJumpWithoutEffects(Bytecode bytecode); |
505 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode); | |
506 } | |
507 | 465 |
508 // Returns true if |bytecode| has no effects. These bytecodes only manipulate | 466 // Return true if |bytecode| is a register load without effects, |
509 // interpreter frame state and will never throw. | 467 // e.g. Mov, Star, LdrUndefined. |
510 static CONSTEXPR bool IsWithoutExternalSideEffects(Bytecode bytecode) { | 468 static bool IsRegisterLoadWithoutEffects(Bytecode bytecode); |
511 return (IsAccumulatorLoadWithoutEffects(bytecode) || | |
512 IsRegisterLoadWithoutEffects(bytecode) || | |
513 bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode)); | |
514 } | |
515 | 469 |
516 // Returns true if the bytecode is Ldar or Star. | 470 // Returns true if |bytecode| has no effects. |
517 static CONSTEXPR bool IsLdarOrStar(Bytecode bytecode) { | 471 static bool IsWithoutExternalSideEffects(Bytecode bytecode); |
518 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar; | |
519 } | |
520 | |
521 // Returns true if |bytecode| puts a name in the accumulator. | |
522 static CONSTEXPR bool PutsNameInAccumulator(Bytecode bytecode) { | |
523 return bytecode == Bytecode::kTypeOf; | |
524 } | |
525 | |
526 // Returns true if the bytecode is a call or a constructor call. | |
527 static CONSTEXPR bool IsCallOrNew(Bytecode bytecode) { | |
528 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || | |
529 bytecode == Bytecode::kNew; | |
530 } | |
531 | |
532 // Returns true if the bytecode is a call to the runtime. | |
533 static CONSTEXPR bool IsCallRuntime(Bytecode bytecode) { | |
534 return bytecode == Bytecode::kCallRuntime || | |
535 bytecode == Bytecode::kCallRuntimeForPair || | |
536 bytecode == Bytecode::kInvokeIntrinsic; | |
537 } | |
538 | |
539 // Returns true if the bytecode is a scaling prefix bytecode. | |
540 static CONSTEXPR bool IsPrefixScalingBytecode(Bytecode bytecode) { | |
541 return bytecode == Bytecode::kExtraWide || bytecode == Bytecode::kWide || | |
542 bytecode == Bytecode::kDebugBreakExtraWide || | |
543 bytecode == Bytecode::kDebugBreakWide; | |
544 } | |
545 | |
546 // Returns the number of values which |bytecode| returns. | |
547 static CONSTEXPR size_t ReturnCount(Bytecode bytecode) { | |
548 return bytecode == Bytecode::kReturn ? 1 : 0; | |
549 } | |
550 | |
551 // Returns the number of operands expected by |bytecode|. | |
552 static int NumberOfOperands(Bytecode bytecode) { | |
553 DCHECK(bytecode <= Bytecode::kLast); | |
554 return kOperandCount[static_cast<size_t>(bytecode)]; | |
555 } | |
556 | 472 |
557 // Returns the i-th operand of |bytecode|. | 473 // Returns the i-th operand of |bytecode|. |
558 static OperandType GetOperandType(Bytecode bytecode, int i) { | 474 static OperandType GetOperandType(Bytecode bytecode, int i); |
559 DCHECK_LE(bytecode, Bytecode::kLast); | |
560 DCHECK_LT(i, NumberOfOperands(bytecode)); | |
561 DCHECK_GE(i, 0); | |
562 return GetOperandTypes(bytecode)[i]; | |
563 } | |
564 | 475 |
565 // Returns a pointer to an array of operand types terminated in | 476 // Returns a pointer to an array of operand types terminated in |
566 // OperandType::kNone. | 477 // OperandType::kNone. |
567 static const OperandType* GetOperandTypes(Bytecode bytecode) { | 478 static const OperandType* GetOperandTypes(Bytecode bytecode); |
568 DCHECK(bytecode <= Bytecode::kLast); | |
569 return kOperandTypes[static_cast<size_t>(bytecode)]; | |
570 } | |
571 | 479 |
572 static bool OperandIsScalableSignedByte(Bytecode bytecode, | 480 // Returns a pointer to an array of operand type info terminated in |
573 int operand_index) { | 481 // OperandTypeInfo::kNone. |
574 DCHECK(bytecode <= Bytecode::kLast); | 482 static const OperandTypeInfo* GetOperandTypeInfos(Bytecode bytecode); |
575 return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] == | |
576 OperandTypeInfo::kScalableSignedByte; | |
577 } | |
578 | |
579 static bool OperandIsScalableUnsignedByte(Bytecode bytecode, | |
580 int operand_index) { | |
581 DCHECK(bytecode <= Bytecode::kLast); | |
582 return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] == | |
583 OperandTypeInfo::kScalableUnsignedByte; | |
584 } | |
585 | |
586 static bool OperandIsScalable(Bytecode bytecode, int operand_index) { | |
587 return OperandIsScalableSignedByte(bytecode, operand_index) || | |
588 OperandIsScalableUnsignedByte(bytecode, operand_index); | |
589 } | |
590 | |
591 // Returns true if the bytecode has wider operand forms. | |
592 static bool IsBytecodeWithScalableOperands(Bytecode bytecode); | |
593 | 483 |
594 // Returns the size of the i-th operand of |bytecode|. | 484 // Returns the size of the i-th operand of |bytecode|. |
595 static OperandSize GetOperandSize(Bytecode bytecode, int i, | 485 static OperandSize GetOperandSize(Bytecode bytecode, int i, |
596 OperandScale operand_scale) { | 486 OperandScale operand_scale); |
597 CHECK_LT(i, NumberOfOperands(bytecode)); | |
598 return GetOperandSizes(bytecode, operand_scale)[i]; | |
599 } | |
600 | |
601 // Returns the operand sizes of |bytecode| with scale |operand_scale|. | |
602 static const OperandSize* GetOperandSizes(Bytecode bytecode, | |
603 OperandScale operand_scale) { | |
604 DCHECK(bytecode <= Bytecode::kLast); | |
605 DCHECK_GE(operand_scale, OperandScale::kSingle); | |
606 DCHECK_LE(operand_scale, OperandScale::kLast); | |
607 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 && | |
608 OperandScale::kLast == OperandScale::kQuadruple); | |
609 int scale_index = static_cast<int>(operand_scale) >> 1; | |
610 return kOperandSizes[static_cast<size_t>(bytecode)][scale_index]; | |
611 } | |
612 | 487 |
613 // Returns the offset of the i-th operand of |bytecode| relative to the start | 488 // Returns the offset of the i-th operand of |bytecode| relative to the start |
614 // of the bytecode. | 489 // of the bytecode. |
615 static int GetOperandOffset(Bytecode bytecode, int i, | 490 static int GetOperandOffset(Bytecode bytecode, int i, |
616 OperandScale operand_scale); | 491 OperandScale operand_scale); |
617 | 492 |
| 493 // Returns a debug break bytecode to replace |bytecode|. |
| 494 static Bytecode GetDebugBreak(Bytecode bytecode); |
| 495 |
618 // Returns the size of the bytecode including its operands for the | 496 // Returns the size of the bytecode including its operands for the |
619 // given |operand_scale|. | 497 // given |operand_scale|. |
620 static int Size(Bytecode bytecode, OperandScale operand_scale) { | 498 static int Size(Bytecode bytecode, OperandScale operand_scale); |
621 DCHECK(bytecode <= Bytecode::kLast); | |
622 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 && | |
623 OperandScale::kLast == OperandScale::kQuadruple); | |
624 int scale_index = static_cast<int>(operand_scale) >> 1; | |
625 return kBytecodeSizes[static_cast<size_t>(bytecode)][scale_index]; | |
626 } | |
627 | 499 |
628 // Returns a debug break bytecode to replace |bytecode|. | 500 // Returns the size of |operand|. |
629 static Bytecode GetDebugBreak(Bytecode bytecode); | 501 static OperandSize SizeOfOperand(OperandType operand, OperandScale scale); |
| 502 |
| 503 // Returns the number of values which |bytecode| returns. |
| 504 static size_t ReturnCount(Bytecode bytecode); |
| 505 |
| 506 // Returns true if the bytecode is a conditional jump taking |
| 507 // an immediate byte operand (OperandType::kImm). |
| 508 static bool IsConditionalJumpImmediate(Bytecode bytecode); |
| 509 |
| 510 // Returns true if the bytecode is a conditional jump taking |
| 511 // a constant pool entry (OperandType::kIdx). |
| 512 static bool IsConditionalJumpConstant(Bytecode bytecode); |
| 513 |
| 514 // Returns true if the bytecode is a conditional jump taking |
| 515 // any kind of operand. |
| 516 static bool IsConditionalJump(Bytecode bytecode); |
| 517 |
| 518 // Returns true if the bytecode is a jump or a conditional jump taking |
| 519 // an immediate byte operand (OperandType::kImm). |
| 520 static bool IsJumpImmediate(Bytecode bytecode); |
| 521 |
| 522 // Returns true if the bytecode is a jump or conditional jump taking a |
| 523 // constant pool entry (OperandType::kIdx). |
| 524 static bool IsJumpConstant(Bytecode bytecode); |
| 525 |
| 526 // Returns true if the bytecode is a jump or conditional jump taking |
| 527 // any kind of operand. |
| 528 static bool IsJump(Bytecode bytecode); |
| 529 |
| 530 // Returns true if the bytecode is a jump that internally coerces the |
| 531 // accumulator to a boolean. |
| 532 static bool IsJumpIfToBoolean(Bytecode bytecode); |
630 | 533 |
631 // Returns the equivalent jump bytecode without the accumulator coercion. | 534 // Returns the equivalent jump bytecode without the accumulator coercion. |
632 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode); | 535 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode); |
633 | 536 |
| 537 // Returns true if the bytecode is a conditional jump, a jump, or a return. |
| 538 static bool IsJumpOrReturn(Bytecode bytecode); |
| 539 |
| 540 // Returns true if the bytecode is a call or a constructor call. |
| 541 static bool IsCallOrNew(Bytecode bytecode); |
| 542 |
| 543 // Returns true if the bytecode is a call to the runtime. |
| 544 static bool IsCallRuntime(Bytecode bytecode); |
| 545 |
634 // Returns true if the bytecode is a debug break. | 546 // Returns true if the bytecode is a debug break. |
635 static bool IsDebugBreak(Bytecode bytecode); | 547 static bool IsDebugBreak(Bytecode bytecode); |
636 | 548 |
| 549 // Returns true if the bytecode is Ldar or Star. |
| 550 static bool IsLdarOrStar(Bytecode bytecode); |
| 551 |
| 552 // Returns true if the bytecode has wider operand forms. |
| 553 static bool IsBytecodeWithScalableOperands(Bytecode bytecode); |
| 554 |
| 555 // Returns true if the bytecode is a scaling prefix bytecode. |
| 556 static bool IsPrefixScalingBytecode(Bytecode bytecode); |
| 557 |
| 558 // Returns true if |bytecode| puts a name in the accumulator. |
| 559 static bool PutsNameInAccumulator(Bytecode bytecode); |
| 560 |
637 // Returns true if |operand_type| is any type of register operand. | 561 // Returns true if |operand_type| is any type of register operand. |
638 static bool IsRegisterOperandType(OperandType operand_type); | 562 static bool IsRegisterOperandType(OperandType operand_type); |
639 | 563 |
640 // Returns true if |operand_type| represents a register used as an input. | 564 // Returns true if |operand_type| represents a register used as an input. |
641 static bool IsRegisterInputOperandType(OperandType operand_type); | 565 static bool IsRegisterInputOperandType(OperandType operand_type); |
642 | 566 |
643 // Returns true if |operand_type| represents a register used as an output. | 567 // Returns true if |operand_type| represents a register used as an output. |
644 static bool IsRegisterOutputOperandType(OperandType operand_type); | 568 static bool IsRegisterOutputOperandType(OperandType operand_type); |
645 | 569 |
646 // Returns true if the handler for |bytecode| should look ahead and inline a | 570 // Returns true if the handler for |bytecode| should look ahead and inline a |
647 // dispatch to a Star bytecode. | 571 // dispatch to a Star bytecode. |
648 static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale); | 572 static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale); |
649 | 573 |
650 // Returns the number of registers represented by a register operand. For | 574 // Returns the number of registers represented by a register operand. For |
651 // instance, a RegPair represents two registers. | 575 // instance, a RegPair represents two registers. |
652 static int GetNumberOfRegistersRepresentedBy(OperandType operand_type) { | 576 static int GetNumberOfRegistersRepresentedBy(OperandType operand_type); |
653 switch (operand_type) { | |
654 case OperandType::kMaybeReg: | |
655 case OperandType::kReg: | |
656 case OperandType::kRegOut: | |
657 return 1; | |
658 case OperandType::kRegPair: | |
659 case OperandType::kRegOutPair: | |
660 return 2; | |
661 case OperandType::kRegOutTriple: | |
662 return 3; | |
663 default: | |
664 return 0; | |
665 } | |
666 return 0; | |
667 } | |
668 | 577 |
669 // Returns the size of |operand| for |operand_scale|. | 578 // Returns true if |operand_type| is a maybe register operand |
670 static OperandSize SizeOfOperand(OperandType operand, OperandScale scale); | 579 // (kMaybeReg). |
| 580 static bool IsMaybeRegisterOperandType(OperandType operand_type); |
671 | 581 |
672 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId). | 582 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId). |
673 static bool IsRuntimeIdOperandType(OperandType operand_type); | 583 static bool IsRuntimeIdOperandType(OperandType operand_type); |
674 | 584 |
675 // Returns true if |operand_type| is unsigned, false if signed. | 585 // Returns true if |operand_type| is unsigned, false if signed. |
676 static bool IsUnsignedOperandType(OperandType operand_type); | 586 static bool IsUnsignedOperandType(OperandType operand_type); |
677 | 587 |
678 // Returns true if a handler is generated for a bytecode at a given | 588 // Returns true if a handler is generated for a bytecode at a given |
679 // operand scale. All bytecodes have handlers at OperandScale::kSingle, | 589 // operand scale. All bytecodes have handlers at OperandScale::kSingle, |
680 // but only bytecodes with scalable operands have handlers with larger | 590 // but only bytecodes with scalable operands have handlers with larger |
681 // OperandScale values. | 591 // OperandScale values. |
682 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale); | 592 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale); |
683 | 593 |
684 // Return the operand scale required to hold a signed operand with |value|. | 594 // Return the operand size required to hold a signed operand. |
685 static OperandScale ScaleForSignedOperand(int32_t value) { | 595 static OperandSize SizeForSignedOperand(int value); |
686 if (value >= kMinInt8 && value <= kMaxInt8) { | |
687 return OperandScale::kSingle; | |
688 } else if (value >= kMinInt16 && value <= kMaxInt16) { | |
689 return OperandScale::kDouble; | |
690 } else { | |
691 return OperandScale::kQuadruple; | |
692 } | |
693 } | |
694 | 596 |
695 // Return the operand scale required to hold an unsigned operand with |value|. | 597 // Return the operand size required to hold an unsigned operand. |
696 static OperandScale ScaleForUnsignedOperand(uint32_t value) { | 598 static OperandSize SizeForUnsignedOperand(uint32_t value); |
697 if (value <= kMaxUInt8) { | |
698 return OperandScale::kSingle; | |
699 } else if (value <= kMaxUInt16) { | |
700 return OperandScale::kDouble; | |
701 } else { | |
702 return OperandScale::kQuadruple; | |
703 } | |
704 } | |
705 | |
706 // Return the operand size required to hold an unsigned operand with |value|. | |
707 static OperandSize SizeForUnsignedOperand(uint32_t value) { | |
708 if (value <= kMaxUInt8) { | |
709 return OperandSize::kByte; | |
710 } else if (value <= kMaxUInt16) { | |
711 return OperandSize::kShort; | |
712 } else { | |
713 return OperandSize::kQuad; | |
714 } | |
715 } | |
716 | |
717 private: | |
718 static const OperandType* const kOperandTypes[]; | |
719 static const OperandTypeInfo* const kOperandTypeInfos[]; | |
720 static const int kOperandCount[]; | |
721 static const int kNumberOfRegisterOperands[]; | |
722 static const AccumulatorUse kAccumulatorUse[]; | |
723 static const bool kIsScalable[]; | |
724 static const int kBytecodeSizes[][3]; | |
725 static const OperandSize* const kOperandSizes[][3]; | |
726 }; | 599 }; |
727 | 600 |
728 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr. | |
729 // See crbug.com/603131. | |
730 #undef CONSTEXPR | |
731 | |
732 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode); | 601 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode); |
| 602 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use); |
| 603 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale); |
| 604 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size); |
| 605 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type); |
733 | 606 |
734 } // namespace interpreter | 607 } // namespace interpreter |
735 } // namespace internal | 608 } // namespace internal |
736 } // namespace v8 | 609 } // namespace v8 |
737 | 610 |
738 #endif // V8_INTERPRETER_BYTECODES_H_ | 611 #endif // V8_INTERPRETER_BYTECODES_H_ |
OLD | NEW |