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

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: Addressed review comments. 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(BytecodeArrayBuilder& array_builder)
oth 2015/11/24 13:49:26 The array_builder argument and member should be co
mythria 2015/11/24 14:33:06 Done.
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;
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 BytecodeArrayBuilder& array_builder;
oth 2015/11/24 13:49:26 Coding style is for members of a class to end with
mythria 2015/11/24 14:33:06 Done.
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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 } 563 }
507 564
508 565
509 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { 566 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
510 Output(Bytecode::kPopContext, context.ToOperand()); 567 Output(Bytecode::kPopContext, context.ToOperand());
511 return *this; 568 return *this;
512 } 569 }
513 570
514 571
515 bool BytecodeArrayBuilder::NeedToBooleanCast() { 572 bool BytecodeArrayBuilder::NeedToBooleanCast() {
516 if (!LastBytecodeInSameBlock()) { 573 PreviousBytecodeHelper previous_bytecode(*this);
517 // If the previous bytecode was from a different block return false. 574 switch (previous_bytecode.GetBytecode()) {
518 return true;
519 }
520
521 // If the previous bytecode puts a boolean in the accumulator return true.
522 switch (Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_))) {
523 case Bytecode::kToBoolean: 575 case Bytecode::kToBoolean:
524 UNREACHABLE(); 576 UNREACHABLE();
577 // If the previous bytecode puts a boolean in the accumulator return true.
525 case Bytecode::kLdaTrue: 578 case Bytecode::kLdaTrue:
526 case Bytecode::kLdaFalse: 579 case Bytecode::kLdaFalse:
527 case Bytecode::kLogicalNot: 580 case Bytecode::kLogicalNot:
528 case Bytecode::kTestEqual: 581 case Bytecode::kTestEqual:
529 case Bytecode::kTestNotEqual: 582 case Bytecode::kTestNotEqual:
530 case Bytecode::kTestEqualStrict: 583 case Bytecode::kTestEqualStrict:
531 case Bytecode::kTestNotEqualStrict: 584 case Bytecode::kTestNotEqualStrict:
532 case Bytecode::kTestLessThan: 585 case Bytecode::kTestLessThan:
533 case Bytecode::kTestLessThanOrEqual: 586 case Bytecode::kTestLessThanOrEqual:
534 case Bytecode::kTestGreaterThan: 587 case Bytecode::kTestGreaterThan:
535 case Bytecode::kTestGreaterThanOrEqual: 588 case Bytecode::kTestGreaterThanOrEqual:
536 case Bytecode::kTestInstanceOf: 589 case Bytecode::kTestInstanceOf:
537 case Bytecode::kTestIn: 590 case Bytecode::kTestIn:
538 case Bytecode::kForInDone: 591 case Bytecode::kForInDone:
539 return false; 592 return false;
593 // Also handles the case where the previous bytecode was in a different
594 // block.
540 default: 595 default:
541 return true; 596 return true;
542 } 597 }
543 } 598 }
544 599
545 600
546 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { 601 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() {
602 PreviousBytecodeHelper previous_bytecode(*this);
547 // If the previous bytecode puts a boolean in the accumulator 603 // If the previous bytecode puts a boolean in the accumulator
548 // there is no need to emit an instruction. 604 // there is no need to emit an instruction.
549 if (NeedToBooleanCast()) { 605 if (NeedToBooleanCast()) {
550 Output(Bytecode::kToBoolean); 606 switch (previous_bytecode.GetBytecode()) {
607 // If the previous bytecode is a constant evaluate it and return false.
608 case Bytecode::kLdaZero: {
609 LoadFalse();
610 break;
611 }
612 case Bytecode::kLdaSmi8: {
613 LoadBooleanConstant(previous_bytecode.GetOperand(0) != 0);
614 break;
615 }
616 case Bytecode::kLdaConstant: {
617 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
618 LoadBooleanConstant(object->BooleanValue());
619 break;
620 }
621 default:
622 Output(Bytecode::kToBoolean);
623 }
551 } 624 }
552 return *this; 625 return *this;
553 } 626 }
554 627
555 628
556 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { 629 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
557 Output(Bytecode::kToObject); 630 Output(Bytecode::kToObject);
558 return *this; 631 return *this;
559 } 632 }
560 633
561 634
562 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { 635 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
636 PreviousBytecodeHelper previous_bytecode(*this);
637 switch (previous_bytecode.GetBytecode()) {
638 case Bytecode::kLdaConstantWide:
639 case Bytecode::kLdaConstant: {
640 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
641 if (object->IsName()) return *this;
642 break;
643 }
644 case Bytecode::kToName:
645 case Bytecode::kTypeOf:
646 return *this;
647 default:
648 break;
649 }
563 Output(Bytecode::kToName); 650 Output(Bytecode::kToName);
564 return *this; 651 return *this;
565 } 652 }
566 653
567 654
568 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() { 655 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() {
569 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns 656 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns
570 // a number. 657 // a number.
571 Output(Bytecode::kToNumber); 658 Output(Bytecode::kToNumber);
572 return *this; 659 return *this;
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 } 1071 }
985 1072
986 1073
987 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { 1074 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
988 return last_bytecode_start_ < bytecodes()->size() && 1075 return last_bytecode_start_ < bytecodes()->size() &&
989 last_bytecode_start_ >= last_block_end_; 1076 last_bytecode_start_ >= last_block_end_;
990 } 1077 }
991 1078
992 1079
993 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { 1080 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
994 if (!LastBytecodeInSameBlock()) return false; 1081 PreviousBytecodeHelper previous_bytecode(*this);
995 Bytecode previous_bytecode = 1082 if (previous_bytecode.GetBytecode() == Bytecode::kLdar ||
996 Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_)); 1083 previous_bytecode.GetBytecode() == Bytecode::kStar) {
997 if (previous_bytecode == Bytecode::kLdar || 1084 if (reg == Register::FromOperand(previous_bytecode.GetOperand(0))) {
998 previous_bytecode == Bytecode::kStar) {
999 size_t operand_offset = last_bytecode_start_ +
1000 Bytecodes::GetOperandOffset(previous_bytecode, 0);
1001 if (reg == Register::FromOperand(bytecodes()->at(operand_offset))) {
1002 return true; 1085 return true;
1003 } 1086 }
1004 } 1087 }
1005 return false; 1088 return false;
1006 } 1089 }
1007 1090
1008 1091
1009 // static 1092 // static
1010 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { 1093 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
1011 switch (op) { 1094 switch (op) {
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 DCHECK_GT(next_consecutive_count_, 0); 1413 DCHECK_GT(next_consecutive_count_, 0);
1331 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); 1414 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_);
1332 allocated_.push_back(next_consecutive_register_); 1415 allocated_.push_back(next_consecutive_register_);
1333 next_consecutive_count_--; 1416 next_consecutive_count_--;
1334 return Register(next_consecutive_register_++); 1417 return Register(next_consecutive_register_++);
1335 } 1418 }
1336 1419
1337 } // namespace interpreter 1420 } // namespace interpreter
1338 } // namespace internal 1421 } // namespace internal
1339 } // namespace v8 1422 } // 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