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

Side by Side Diff: src/interpreter/bytecode-array-builder.cc

Issue 1468003002: [Interpreter] Add support for cast operators to bytecode graph builder and (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebased the patch and removed unused definitions of matcher classes in unittests Created 5 years 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/bytecode-array-builder.h" 5 #include "src/interpreter/bytecode-array-builder.h"
6 6
7 namespace v8 { 7 namespace v8 {
8 namespace internal { 8 namespace internal {
9 namespace interpreter { 9 namespace interpreter {
10 10
11 class BytecodeArrayBuilder::PreviousBytecodeHelper {
12 public:
13 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder)
14 : array_builder_(array_builder) {}
15
16 Bytecode GetBytecode() const {
17 // Returns the previous bytecode in the same basicblock. If there is none it
18 // returns Bytecode::kLast.
19 if (!array_builder_.LastBytecodeInSameBlock()) {
20 return Bytecode::kLast;
rmcilroy 2015/12/07 11:56:03 Bytecode::kLast is the same as the last valid byte
21 }
22 return Bytecodes::FromByte(
23 array_builder_.bytecodes()->at(array_builder_.last_bytecode_start_));
24 }
25
26 uint32_t GetOperand(int operand_index) const {
27 Bytecode bytecode = GetBytecode();
28 DCHECK_GE(operand_index, 0);
29 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode));
30 size_t operand_offset =
31 array_builder_.last_bytecode_start_ +
32 Bytecodes::GetOperandOffset(bytecode, operand_index);
33 OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index);
34 switch (size) {
35 default:
36 case OperandSize::kNone:
37 UNREACHABLE();
38 case OperandSize::kByte:
39 return static_cast<uint32_t>(
40 array_builder_.bytecodes()->at(operand_offset));
41 case OperandSize::kShort:
42 uint16_t operand =
43 (array_builder_.bytecodes()->at(operand_offset) << 8) +
44 array_builder_.bytecodes()->at(operand_offset + 1);
45 return static_cast<uint32_t>(operand);
46 }
47 }
48
49 Handle<Object> GetConstantForIndexOperand(int operand_index) const {
50 return array_builder_.constants_.at(GetOperand(operand_index));
51 }
52
53 private:
54 const BytecodeArrayBuilder& array_builder_;
55 };
56
57
11 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) 58 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone)
12 : isolate_(isolate), 59 : isolate_(isolate),
13 zone_(zone), 60 zone_(zone),
14 bytecodes_(zone), 61 bytecodes_(zone),
15 bytecode_generated_(false), 62 bytecode_generated_(false),
16 last_block_end_(0), 63 last_block_end_(0),
17 last_bytecode_start_(~0), 64 last_bytecode_start_(~0),
18 exit_seen_in_block_(false), 65 exit_seen_in_block_(false),
19 constants_map_(isolate->heap(), zone), 66 constants_map_(isolate->heap(), zone),
20 constants_(zone), 67 constants_(zone),
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 return *this; 317 return *this;
271 } 318 }
272 319
273 320
274 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { 321 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
275 Output(Bytecode::kLdaFalse); 322 Output(Bytecode::kLdaFalse);
276 return *this; 323 return *this;
277 } 324 }
278 325
279 326
327 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadBooleanConstant(bool value) {
328 if (value) {
329 LoadTrue();
330 } else {
331 LoadFalse();
332 }
333 return *this;
334 }
335
336
280 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( 337 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
281 Register reg) { 338 Register reg) {
282 if (!IsRegisterInAccumulator(reg)) { 339 if (!IsRegisterInAccumulator(reg)) {
283 Output(Bytecode::kLdar, reg.ToOperand()); 340 Output(Bytecode::kLdar, reg.ToOperand());
284 } 341 }
285 return *this; 342 return *this;
286 } 343 }
287 344
288 345
289 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( 346 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 } 573 }
517 574
518 575
519 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { 576 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
520 Output(Bytecode::kPopContext, context.ToOperand()); 577 Output(Bytecode::kPopContext, context.ToOperand());
521 return *this; 578 return *this;
522 } 579 }
523 580
524 581
525 bool BytecodeArrayBuilder::NeedToBooleanCast() { 582 bool BytecodeArrayBuilder::NeedToBooleanCast() {
526 if (!LastBytecodeInSameBlock()) { 583 PreviousBytecodeHelper previous_bytecode(*this);
527 // If the previous bytecode was from a different block return false. 584 switch (previous_bytecode.GetBytecode()) {
528 return true;
529 }
530
531 // If the previous bytecode puts a boolean in the accumulator return true.
532 switch (Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_))) {
533 case Bytecode::kToBoolean: 585 case Bytecode::kToBoolean:
534 UNREACHABLE(); 586 UNREACHABLE();
587 // If the previous bytecode puts a boolean in the accumulator return true.
535 case Bytecode::kLdaTrue: 588 case Bytecode::kLdaTrue:
536 case Bytecode::kLdaFalse: 589 case Bytecode::kLdaFalse:
537 case Bytecode::kLogicalNot: 590 case Bytecode::kLogicalNot:
538 case Bytecode::kTestEqual: 591 case Bytecode::kTestEqual:
539 case Bytecode::kTestNotEqual: 592 case Bytecode::kTestNotEqual:
540 case Bytecode::kTestEqualStrict: 593 case Bytecode::kTestEqualStrict:
541 case Bytecode::kTestNotEqualStrict: 594 case Bytecode::kTestNotEqualStrict:
542 case Bytecode::kTestLessThan: 595 case Bytecode::kTestLessThan:
543 case Bytecode::kTestLessThanOrEqual: 596 case Bytecode::kTestLessThanOrEqual:
544 case Bytecode::kTestGreaterThan: 597 case Bytecode::kTestGreaterThan:
545 case Bytecode::kTestGreaterThanOrEqual: 598 case Bytecode::kTestGreaterThanOrEqual:
546 case Bytecode::kTestInstanceOf: 599 case Bytecode::kTestInstanceOf:
547 case Bytecode::kTestIn: 600 case Bytecode::kTestIn:
548 case Bytecode::kForInDone: 601 case Bytecode::kForInDone:
549 return false; 602 return false;
603 // Also handles the case where the previous bytecode was in a different
604 // block.
550 default: 605 default:
551 return true; 606 return true;
552 } 607 }
553 } 608 }
554 609
555 610
556 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { 611 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() {
612 PreviousBytecodeHelper previous_bytecode(*this);
557 // If the previous bytecode puts a boolean in the accumulator 613 // If the previous bytecode puts a boolean in the accumulator
558 // there is no need to emit an instruction. 614 // there is no need to emit an instruction.
559 if (NeedToBooleanCast()) { 615 if (NeedToBooleanCast()) {
560 Output(Bytecode::kToBoolean); 616 switch (previous_bytecode.GetBytecode()) {
rmcilroy 2015/12/07 11:56:03 Optional nit - It would be nice to have some tests
617 // If the previous bytecode is a constant evaluate it and return false.
618 case Bytecode::kLdaZero: {
619 LoadFalse();
620 break;
621 }
622 case Bytecode::kLdaSmi8: {
623 LoadBooleanConstant(previous_bytecode.GetOperand(0) != 0);
624 break;
625 }
626 case Bytecode::kLdaConstant: {
627 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
628 LoadBooleanConstant(object->BooleanValue());
629 break;
630 }
631 default:
632 Output(Bytecode::kToBoolean);
633 }
561 } 634 }
562 return *this; 635 return *this;
563 } 636 }
564 637
565 638
566 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { 639 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
567 Output(Bytecode::kToObject); 640 Output(Bytecode::kToObject);
568 return *this; 641 return *this;
569 } 642 }
570 643
571 644
572 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { 645 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
646 PreviousBytecodeHelper previous_bytecode(*this);
647 switch (previous_bytecode.GetBytecode()) {
648 case Bytecode::kLdaConstantWide:
649 case Bytecode::kLdaConstant: {
650 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
651 if (object->IsName()) return *this;
652 break;
653 }
654 case Bytecode::kToName:
655 case Bytecode::kTypeOf:
656 return *this;
657 default:
658 break;
659 }
573 Output(Bytecode::kToName); 660 Output(Bytecode::kToName);
574 return *this; 661 return *this;
575 } 662 }
576 663
577 664
578 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() { 665 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() {
579 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns 666 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns
580 // a number. 667 // a number.
581 Output(Bytecode::kToNumber); 668 Output(Bytecode::kToNumber);
582 return *this; 669 return *this;
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 } 1082 }
996 1083
997 1084
998 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { 1085 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
999 return last_bytecode_start_ < bytecodes()->size() && 1086 return last_bytecode_start_ < bytecodes()->size() &&
1000 last_bytecode_start_ >= last_block_end_; 1087 last_bytecode_start_ >= last_block_end_;
1001 } 1088 }
1002 1089
1003 1090
1004 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { 1091 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
1005 if (!LastBytecodeInSameBlock()) return false; 1092 PreviousBytecodeHelper previous_bytecode(*this);
1006 Bytecode previous_bytecode = 1093 if (previous_bytecode.GetBytecode() == Bytecode::kLdar ||
1007 Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_)); 1094 previous_bytecode.GetBytecode() == Bytecode::kStar) {
1008 if (previous_bytecode == Bytecode::kLdar || 1095 if (reg == Register::FromOperand(previous_bytecode.GetOperand(0))) {
1009 previous_bytecode == Bytecode::kStar) {
1010 size_t operand_offset = last_bytecode_start_ +
1011 Bytecodes::GetOperandOffset(previous_bytecode, 0);
1012 if (reg == Register::FromOperand(bytecodes()->at(operand_offset))) {
1013 return true; 1096 return true;
1014 } 1097 }
1015 } 1098 }
1016 return false; 1099 return false;
1017 } 1100 }
1018 1101
1019 1102
1020 // static 1103 // static
1021 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { 1104 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
1022 switch (op) { 1105 switch (op) {
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 DCHECK_GT(next_consecutive_count_, 0); 1424 DCHECK_GT(next_consecutive_count_, 0);
1342 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); 1425 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_);
1343 allocated_.push_back(next_consecutive_register_); 1426 allocated_.push_back(next_consecutive_register_);
1344 next_consecutive_count_--; 1427 next_consecutive_count_--;
1345 return Register(next_consecutive_register_++); 1428 return Register(next_consecutive_register_++);
1346 } 1429 }
1347 1430
1348 } // namespace interpreter 1431 } // namespace interpreter
1349 } // namespace internal 1432 } // namespace internal
1350 } // namespace v8 1433 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | test/cctest/compiler/test-run-bytecode-graph-builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698