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

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

Issue 1947403002: [interpreter] Introduce bytecode generation pipeline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 7 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 <iomanip> 7 #include <iomanip>
8 8
9 #include "src/frames.h" 9 #include "src/frames.h"
10 #include "src/interpreter/bytecode-traits.h" 10 #include "src/interpreter/bytecode-traits.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 OPERAND_TYPE_LIST(CASE) 67 OPERAND_TYPE_LIST(CASE)
68 #undef CASE 68 #undef CASE
69 } 69 }
70 UNREACHABLE(); 70 UNREACHABLE();
71 return ""; 71 return "";
72 } 72 }
73 73
74 // static 74 // static
75 const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) { 75 const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) {
76 switch (operand_scale) { 76 switch (operand_scale) {
77 case OperandScale::kSingle: 77 #define CASE(Name, _) \
78 return "Single"; 78 case OperandScale::k##Name: \
79 case OperandScale::kDouble: 79 return #Name;
80 return "Double"; 80 OPERAND_SCALE_LIST(CASE)
81 case OperandScale::kQuadruple: 81 #undef CASE
82 return "Quadruple";
83 case OperandScale::kInvalid:
84 UNREACHABLE();
85 } 82 }
83 UNREACHABLE();
86 return ""; 84 return "";
87 } 85 }
88 86
89 // static 87 // static
90 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) { 88 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) {
91 switch (operand_size) { 89 switch (operand_size) {
92 case OperandSize::kNone: 90 case OperandSize::kNone:
93 return "None"; 91 return "None";
94 case OperandSize::kByte: 92 case OperandSize::kByte:
95 return "Byte"; 93 return "Byte";
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 AccumulatorUse::kRead; 232 AccumulatorUse::kRead;
235 } 233 }
236 234
237 // static 235 // static
238 bool Bytecodes::WritesAccumulator(Bytecode bytecode) { 236 bool Bytecodes::WritesAccumulator(Bytecode bytecode) {
239 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) == 237 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) ==
240 AccumulatorUse::kWrite; 238 AccumulatorUse::kWrite;
241 } 239 }
242 240
243 // static 241 // static
242 bool Bytecodes::WritesBooleanToAccumulator(Bytecode bytecode) {
243 switch (bytecode) {
244 case Bytecode::kLdaTrue:
245 case Bytecode::kLdaFalse:
246 case Bytecode::kLogicalNot:
247 case Bytecode::kTestEqual:
248 case Bytecode::kTestNotEqual:
249 case Bytecode::kTestEqualStrict:
250 case Bytecode::kTestLessThan:
251 case Bytecode::kTestLessThanOrEqual:
252 case Bytecode::kTestGreaterThan:
253 case Bytecode::kTestGreaterThanOrEqual:
254 case Bytecode::kTestInstanceOf:
255 case Bytecode::kTestIn:
256 case Bytecode::kForInDone:
257 return true;
258 default:
259 return false;
260 }
261 }
262
263 // static
264 bool Bytecodes::IsAccumulatorLoadWithoutEffects(Bytecode bytecode) {
265 switch (bytecode) {
266 case Bytecode::kLdaZero:
267 case Bytecode::kLdaSmi:
268 case Bytecode::kLdaUndefined:
269 case Bytecode::kLdaNull:
270 case Bytecode::kLdaTheHole:
271 case Bytecode::kLdaTrue:
272 case Bytecode::kLdaFalse:
273 case Bytecode::kLdaConstant:
274 case Bytecode::kLdar:
275 return true;
276 default:
277 return false;
278 }
279 }
280
281 // static
244 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { 282 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
283 DCHECK_LE(bytecode, Bytecode::kLast);
284 DCHECK_LT(i, NumberOfOperands(bytecode));
285 DCHECK_GE(i, 0);
286 return GetOperandTypes(bytecode)[i];
287 }
288
289 // static
290 const OperandType* Bytecodes::GetOperandTypes(Bytecode bytecode) {
245 DCHECK(bytecode <= Bytecode::kLast); 291 DCHECK(bytecode <= Bytecode::kLast);
246 switch (bytecode) { 292 switch (bytecode) {
247 #define CASE(Name, ...) \ 293 #define CASE(Name, ...) \
248 case Bytecode::k##Name: \ 294 case Bytecode::k##Name: \
249 return BytecodeTraits<__VA_ARGS__>::GetOperandType(i); 295 return BytecodeTraits<__VA_ARGS__>::GetOperandTypes();
250 BYTECODE_LIST(CASE) 296 BYTECODE_LIST(CASE)
251 #undef CASE 297 #undef CASE
252 } 298 }
253 UNREACHABLE(); 299 UNREACHABLE();
254 return OperandType::kNone; 300 return nullptr;
255 } 301 }
256 302
257 // static 303 // static
258 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i, 304 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i,
259 OperandScale operand_scale) { 305 OperandScale operand_scale) {
260 OperandType op_type = GetOperandType(bytecode, i); 306 DCHECK(bytecode <= Bytecode::kLast);
261 return ScaledOperandSize(op_type, operand_scale); 307 switch (bytecode) {
308 #define CASE(Name, ...) \
309 case Bytecode::k##Name: \
310 return BytecodeTraits<__VA_ARGS__>::GetOperandSize(i, operand_scale);
311 BYTECODE_LIST(CASE)
312 #undef CASE
313 }
314 UNREACHABLE();
315 return OperandSize::kNone;
262 } 316 }
263 317
264 // static 318 // static
265 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) { 319 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) {
266 DCHECK(bytecode <= Bytecode::kLast); 320 DCHECK(bytecode <= Bytecode::kLast);
267 switch (bytecode) { 321 switch (bytecode) {
268 #define CASE(Name, ...) \ 322 #define CASE(Name, ...) \
269 case Bytecode::k##Name: \ 323 case Bytecode::k##Name: \
270 typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \ 324 typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \
271 return Name##Trait::kRegisterOperandBitmap; 325 return Name##Trait::kRegisterOperandBitmap;
272 BYTECODE_LIST(CASE) 326 BYTECODE_LIST(CASE)
273 #undef CASE 327 #undef CASE
274 } 328 }
275 UNREACHABLE(); 329 UNREACHABLE();
276 return false; 330 return false;
277 } 331 }
278 332
279 // static 333 // static
280 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, 334 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
281 OperandScale operand_scale) { 335 OperandScale operand_scale) {
336 DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
282 // TODO(oth): restore this to a statically determined constant. 337 // TODO(oth): restore this to a statically determined constant.
283 int offset = 1; 338 int offset = 1;
284 for (int operand_index = 0; operand_index < i; ++operand_index) { 339 for (int operand_index = 0; operand_index < i; ++operand_index) {
285 OperandSize operand_size = 340 OperandSize operand_size =
286 GetOperandSize(bytecode, operand_index, operand_scale); 341 GetOperandSize(bytecode, operand_index, operand_scale);
287 offset += static_cast<int>(operand_size); 342 offset += static_cast<int>(operand_size);
288 } 343 }
289 return offset; 344 return offset;
290 } 345 }
291 346
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { 391 bool Bytecodes::IsJumpConstant(Bytecode bytecode) {
337 return bytecode == Bytecode::kJumpConstant || 392 return bytecode == Bytecode::kJumpConstant ||
338 IsConditionalJumpConstant(bytecode); 393 IsConditionalJumpConstant(bytecode);
339 } 394 }
340 395
341 // static 396 // static
342 bool Bytecodes::IsJump(Bytecode bytecode) { 397 bool Bytecodes::IsJump(Bytecode bytecode) {
343 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); 398 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
344 } 399 }
345 400
401 // static
402 bool Bytecodes::IsJumpIfToBoolean(Bytecode bytecode) {
403 return bytecode == Bytecode::kJumpIfToBooleanTrue ||
404 bytecode == Bytecode::kJumpIfToBooleanFalse ||
405 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
406 bytecode == Bytecode::kJumpIfToBooleanFalseConstant;
407 }
408
409 // static
410 Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) {
411 switch (bytecode) {
412 case Bytecode::kJumpIfToBooleanTrue:
413 return Bytecode::kJumpIfTrue;
414 case Bytecode::kJumpIfToBooleanFalse:
415 return Bytecode::kJumpIfFalse;
416 case Bytecode::kJumpIfToBooleanTrueConstant:
417 return Bytecode::kJumpIfTrueConstant;
418 case Bytecode::kJumpIfToBooleanFalseConstant:
419 return Bytecode::kJumpIfFalseConstant;
420 default:
421 break;
422 }
423 UNREACHABLE();
424 return Bytecode::kIllegal;
425 }
346 426
347 // static 427 // static
348 bool Bytecodes::IsCallOrNew(Bytecode bytecode) { 428 bool Bytecodes::IsCallOrNew(Bytecode bytecode) {
349 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || 429 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall ||
350 bytecode == Bytecode::kNew; 430 bytecode == Bytecode::kNew;
351 } 431 }
352 432
353 // static 433 // static
354 bool Bytecodes::IsCallRuntime(Bytecode bytecode) { 434 bool Bytecodes::IsCallRuntime(Bytecode bytecode) {
355 return bytecode == Bytecode::kCallRuntime || 435 return bytecode == Bytecode::kCallRuntime ||
356 bytecode == Bytecode::kCallRuntimeForPair || 436 bytecode == Bytecode::kCallRuntimeForPair ||
357 bytecode == Bytecode::kInvokeIntrinsic; 437 bytecode == Bytecode::kInvokeIntrinsic;
358 } 438 }
359 439
360 // static 440 // static
361 bool Bytecodes::IsDebugBreak(Bytecode bytecode) { 441 bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
362 switch (bytecode) { 442 switch (bytecode) {
363 #define CASE(Name, ...) case Bytecode::k##Name: 443 #define CASE(Name, ...) case Bytecode::k##Name:
364 DEBUG_BREAK_BYTECODE_LIST(CASE); 444 DEBUG_BREAK_BYTECODE_LIST(CASE);
365 #undef CASE 445 #undef CASE
366 return true; 446 return true;
367 default: 447 default:
368 break; 448 break;
369 } 449 }
370 return false; 450 return false;
371 } 451 }
372 452
373 // static 453 // static
454 bool Bytecodes::IsLdarOrStar(Bytecode bytecode) {
455 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
456 }
457
458 // static
374 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) { 459 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
375 switch (bytecode) { 460 switch (bytecode) {
376 #define CASE(Name, ...) \ 461 #define CASE(Name, ...) \
377 case Bytecode::k##Name: \ 462 case Bytecode::k##Name: \
378 typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \ 463 typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \
379 return Name##Trait::IsScalable(); 464 return Name##Trait::IsScalable();
380 BYTECODE_LIST(CASE) 465 BYTECODE_LIST(CASE)
381 #undef CASE 466 #undef CASE
382 } 467 }
383 UNREACHABLE(); 468 UNREACHABLE();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 case OperandType::k##Name: \ 539 case OperandType::k##Name: \
455 break; 540 break;
456 NON_REGISTER_OPERAND_TYPE_LIST(CASE) 541 NON_REGISTER_OPERAND_TYPE_LIST(CASE)
457 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) 542 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
458 #undef CASE 543 #undef CASE
459 } 544 }
460 return false; 545 return false;
461 } 546 }
462 547
463 // static 548 // static
549 int Bytecodes::GetNumberOfRegistersRepresentedBy(OperandType operand_type) {
550 switch (operand_type) {
551 case OperandType::kMaybeReg:
552 case OperandType::kReg:
553 case OperandType::kRegOut:
554 return 1;
555 case OperandType::kRegPair:
556 case OperandType::kRegOutPair:
557 return 2;
558 case OperandType::kRegOutTriple:
559 return 3;
560 default:
561 UNREACHABLE();
562 }
563 return 0;
564 }
565
566 // static
464 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) { 567 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
465 switch (operand_type) { 568 switch (operand_type) {
466 #define CASE(Name, _) \ 569 #define CASE(Name, _) \
467 case OperandType::k##Name: \ 570 case OperandType::k##Name: \
468 return OperandTraits<OperandType::k##Name>::TypeInfo::kIsUnsigned; 571 return OperandTraits<OperandType::k##Name>::TypeInfo::kIsUnsigned;
469 OPERAND_TYPE_LIST(CASE) 572 OPERAND_TYPE_LIST(CASE)
470 #undef CASE 573 #undef CASE
471 } 574 }
472 UNREACHABLE(); 575 UNREACHABLE();
473 return false; 576 return false;
474 } 577 }
475 578
476 // static 579 // static
477 OperandScale Bytecodes::NextOperandScale(OperandScale operand_scale) { 580 OperandSize Bytecodes::SizeForSignedOperand(int value) {
478 DCHECK(operand_scale >= OperandScale::kSingle && 581 if (kMinInt8 <= value && value <= kMaxInt8) {
479 operand_scale <= OperandScale::kMaxValid); 582 return OperandSize::kByte;
480 return static_cast<OperandScale>(2 * static_cast<int>(operand_scale)); 583 } else if (kMinInt16 <= value && value <= kMaxInt16) {
584 return OperandSize::kShort;
585 } else {
586 return OperandSize::kQuad;
587 }
481 } 588 }
482 589
483 // static 590 // static
591 OperandSize Bytecodes::SizeForUnsignedOperand(int value) {
592 DCHECK_GE(value, 0);
593 if (value <= kMaxUInt8) {
594 return OperandSize::kByte;
595 } else if (value <= kMaxUInt16) {
596 return OperandSize::kShort;
597 } else {
598 return OperandSize::kQuad;
599 }
600 }
601
602 OperandSize Bytecodes::SizeForUnsignedOperand(size_t value) {
603 if (value <= static_cast<size_t>(kMaxUInt8)) {
604 return OperandSize::kByte;
605 } else if (value <= static_cast<size_t>(kMaxUInt16)) {
606 return OperandSize::kShort;
607 } else if (value <= kMaxUInt32) {
608 return OperandSize::kQuad;
609 } else {
610 UNREACHABLE();
611 return OperandSize::kQuad;
612 }
613 }
614
615 OperandScale Bytecodes::OperandSizesToScale(OperandSize size0,
616 OperandSize size1,
617 OperandSize size2,
618 OperandSize size3) {
619 OperandSize upper = std::max(size0, size1);
620 OperandSize lower = std::max(size2, size3);
621 OperandSize result = std::max(upper, lower);
622 // Operand sizes have been scaled before calling this function.
623 // Currently all scalable operands are byte sized at
624 // OperandScale::kSingle.
625 STATIC_ASSERT(static_cast<int>(OperandSize::kByte) ==
626 static_cast<int>(OperandScale::kSingle) &&
627 static_cast<int>(OperandSize::kShort) ==
628 static_cast<int>(OperandScale::kDouble) &&
629 static_cast<int>(OperandSize::kQuad) ==
630 static_cast<int>(OperandScale::kQuadruple));
631 OperandScale operand_scale = static_cast<OperandScale>(result);
632 DCHECK(operand_scale == OperandScale::kSingle ||
633 operand_scale == OperandScale::kDouble ||
634 operand_scale == OperandScale::kQuadruple);
635 return operand_scale;
636 }
637
638 // static
484 Register Bytecodes::DecodeRegisterOperand(const uint8_t* operand_start, 639 Register Bytecodes::DecodeRegisterOperand(const uint8_t* operand_start,
485 OperandType operand_type, 640 OperandType operand_type,
486 OperandScale operand_scale) { 641 OperandScale operand_scale) {
487 DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); 642 DCHECK(Bytecodes::IsRegisterOperandType(operand_type));
488 int32_t operand = 643 int32_t operand =
489 DecodeSignedOperand(operand_start, operand_type, operand_scale); 644 DecodeSignedOperand(operand_start, operand_type, operand_scale);
490 return Register::FromOperand(operand); 645 return Register::FromOperand(operand);
491 } 646 }
492 647
493 // static 648 // static
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } else { 922 } else {
768 std::ostringstream s; 923 std::ostringstream s;
769 s << "r" << index(); 924 s << "r" << index();
770 return s.str(); 925 return s.str();
771 } 926 }
772 } 927 }
773 928
774 } // namespace interpreter 929 } // namespace interpreter
775 } // namespace internal 930 } // namespace internal
776 } // namespace v8 931 } // 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