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

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: 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
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 return *this; 270 return *this;
271 } 271 }
272 272
273 273
274 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { 274 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
275 Output(Bytecode::kLdaFalse); 275 Output(Bytecode::kLdaFalse);
276 return *this; 276 return *this;
277 } 277 }
278 278
279 279
280 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadBooleanConstant(bool value) {
281 if (value) {
282 LoadTrue();
283 } else {
284 LoadFalse();
285 }
286 return *this;
287 }
288
289
280 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( 290 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
281 Register reg) { 291 Register reg) {
282 if (!IsRegisterInAccumulator(reg)) { 292 if (!IsRegisterInAccumulator(reg)) {
283 Output(Bytecode::kLdar, reg.ToOperand()); 293 Output(Bytecode::kLdar, reg.ToOperand());
284 } 294 }
285 return *this; 295 return *this;
286 } 296 }
287 297
288 298
289 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( 299 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 } 516 }
507 517
508 518
509 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { 519 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
510 Output(Bytecode::kPopContext, context.ToOperand()); 520 Output(Bytecode::kPopContext, context.ToOperand());
511 return *this; 521 return *this;
512 } 522 }
513 523
514 524
515 bool BytecodeArrayBuilder::NeedToBooleanCast() { 525 bool BytecodeArrayBuilder::NeedToBooleanCast() {
516 if (!LastBytecodeInSameBlock()) { 526 switch (GetPreviousBytecodeInSameBlock()) {
517 // If the previous bytecode was from a different block return false.
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: 527 case Bytecode::kToBoolean:
524 UNREACHABLE(); 528 UNREACHABLE();
529 // If the previous bytecode puts a boolean in the accumulator return true.
525 case Bytecode::kLdaTrue: 530 case Bytecode::kLdaTrue:
526 case Bytecode::kLdaFalse: 531 case Bytecode::kLdaFalse:
527 case Bytecode::kLogicalNot: 532 case Bytecode::kLogicalNot:
528 case Bytecode::kTestEqual: 533 case Bytecode::kTestEqual:
529 case Bytecode::kTestNotEqual: 534 case Bytecode::kTestNotEqual:
530 case Bytecode::kTestEqualStrict: 535 case Bytecode::kTestEqualStrict:
531 case Bytecode::kTestNotEqualStrict: 536 case Bytecode::kTestNotEqualStrict:
532 case Bytecode::kTestLessThan: 537 case Bytecode::kTestLessThan:
533 case Bytecode::kTestLessThanOrEqual: 538 case Bytecode::kTestLessThanOrEqual:
534 case Bytecode::kTestGreaterThan: 539 case Bytecode::kTestGreaterThan:
535 case Bytecode::kTestGreaterThanOrEqual: 540 case Bytecode::kTestGreaterThanOrEqual:
536 case Bytecode::kTestInstanceOf: 541 case Bytecode::kTestInstanceOf:
537 case Bytecode::kTestIn: 542 case Bytecode::kTestIn:
538 case Bytecode::kForInDone: 543 case Bytecode::kForInDone:
539 return false; 544 return false;
545 // Also handles the case where the previous bytecode was in a different
546 // block.
540 default: 547 default:
541 return true; 548 return true;
542 } 549 }
543 } 550 }
544 551
545 552
546 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { 553 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() {
547 // If the previous bytecode puts a boolean in the accumulator 554 // If the previous bytecode puts a boolean in the accumulator
548 // there is no need to emit an instruction. 555 // there is no need to emit an instruction.
549 if (NeedToBooleanCast()) { 556 if (NeedToBooleanCast()) {
550 Output(Bytecode::kToBoolean); 557 switch (GetPreviousBytecodeInSameBlock()) {
558 // If the previous bytecode is a constant evaluate it and return false.
559 case Bytecode::kLdaZero: {
560 LoadFalse();
561 break;
562 }
563 case Bytecode::kLdaSmi8: {
564 LoadBooleanConstant(GetRawOperand(0) != 0);
565 break;
566 }
567 case Bytecode::kLdaConstant: {
568 Handle<Object> object = GetConstantForIndexOperand(0);
569 LoadBooleanConstant(object->BooleanValue());
570 break;
571 }
572 default:
573 Output(Bytecode::kToBoolean);
574 }
551 } 575 }
552 return *this; 576 return *this;
553 } 577 }
554 578
555 579
556 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { 580 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
557 Output(Bytecode::kToObject); 581 Output(Bytecode::kToObject);
558 return *this; 582 return *this;
559 } 583 }
560 584
561 585
562 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { 586 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
587 Bytecode prev_bytecode = GetPreviousBytecodeInSameBlock();
588 switch (prev_bytecode) {
589 case Bytecode::kLdaConstantWide:
590 case Bytecode::kLdaConstant: {
591 Handle<Object> object = GetConstantForIndexOperand(0);
592 if (object->IsName()) return *this;
593 break;
594 }
595 case Bytecode::kToName:
596 case Bytecode::kTypeOf:
597 return *this;
598 default:
599 break;
600 }
563 Output(Bytecode::kToName); 601 Output(Bytecode::kToName);
564 return *this; 602 return *this;
565 } 603 }
566 604
567 605
568 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() { 606 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() {
569 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns 607 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns
570 // a number. 608 // a number.
571 Output(Bytecode::kToNumber); 609 Output(Bytecode::kToNumber);
572 return *this; 610 return *this;
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 return false; 1021 return false;
984 } 1022 }
985 1023
986 1024
987 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { 1025 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
988 return last_bytecode_start_ < bytecodes()->size() && 1026 return last_bytecode_start_ < bytecodes()->size() &&
989 last_bytecode_start_ >= last_block_end_; 1027 last_bytecode_start_ >= last_block_end_;
990 } 1028 }
991 1029
992 1030
1031 Bytecode BytecodeArrayBuilder::GetPreviousBytecodeInSameBlock() const {
oth 2015/11/23 13:46:41 Suggest renaming to GetPreviousBytecode() as the m
mythria 2015/11/24 12:58:48 I added a helper class that takes BytecodeArrayBui
1032 // Returns the previous bytecode in the same basicblock. If there is none it
1033 // returns Bytecode::kLast.
1034 if (!LastBytecodeInSameBlock()) {
1035 return Bytecode::kLast;
1036 }
1037 return Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_));
1038 }
1039
1040
1041 uint32_t BytecodeArrayBuilder::GetRawOperand(int operand_index) const {
oth 2015/11/23 13:46:41 For clarity, it would be better to call this somet
1042 Bytecode bytecode = GetPreviousBytecodeInSameBlock();
1043 DCHECK_GE(operand_index, 0);
1044 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode));
1045 size_t operand_offset = last_bytecode_start_ +
1046 Bytecodes::GetOperandOffset(bytecode, operand_index);
1047 OperandSize size = Bytecodes::GetOperandSize(GetPreviousBytecodeInSameBlock(),
1048 operand_index);
1049 switch (size) {
1050 default:
1051 case OperandSize::kNone:
1052 UNREACHABLE();
1053 case OperandSize::kByte:
1054 return static_cast<uint32_t>(bytecodes()->at(operand_offset));
1055 case OperandSize::kShort:
1056 uint16_t operand = (bytecodes()->at(operand_offset) << 8) +
1057 bytecodes()->at(operand_offset + 1);
1058 return static_cast<uint32_t>(operand);
1059 }
1060 }
1061
1062
1063 Handle<Object> BytecodeArrayBuilder::GetConstantForIndexOperand(
oth 2015/11/23 13:46:41 GetConstantForIndexOperandOfPreviousBytecode(). Ph
1064 int operand_index) {
1065 return constants_.at(GetRawOperand(operand_index));
1066 }
1067
1068
993 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { 1069 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
994 if (!LastBytecodeInSameBlock()) return false; 1070 Bytecode previous_bytecode = GetPreviousBytecodeInSameBlock();
995 Bytecode previous_bytecode =
996 Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_));
997 if (previous_bytecode == Bytecode::kLdar || 1071 if (previous_bytecode == Bytecode::kLdar ||
998 previous_bytecode == Bytecode::kStar) { 1072 previous_bytecode == Bytecode::kStar) {
999 size_t operand_offset = last_bytecode_start_ + 1073 if (reg == Register::FromOperand(GetRawOperand(0))) {
1000 Bytecodes::GetOperandOffset(previous_bytecode, 0);
1001 if (reg == Register::FromOperand(bytecodes()->at(operand_offset))) {
1002 return true; 1074 return true;
1003 } 1075 }
1004 } 1076 }
1005 return false; 1077 return false;
1006 } 1078 }
1007 1079
1008 1080
1009 // static 1081 // static
1010 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { 1082 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
1011 switch (op) { 1083 switch (op) {
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 DCHECK_GT(next_consecutive_count_, 0); 1402 DCHECK_GT(next_consecutive_count_, 0);
1331 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); 1403 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_);
1332 allocated_.push_back(next_consecutive_register_); 1404 allocated_.push_back(next_consecutive_register_);
1333 next_consecutive_count_--; 1405 next_consecutive_count_--;
1334 return Register(next_consecutive_register_++); 1406 return Register(next_consecutive_register_++);
1335 } 1407 }
1336 1408
1337 } // namespace interpreter 1409 } // namespace interpreter
1338 } // namespace internal 1410 } // namespace internal
1339 } // namespace v8 1411 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698