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

Unified 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, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: src/interpreter/bytecode-array-builder.cc
diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc
index c0de7c0bb1303f76f4cbb893d55efdd497a4b2df..ca070cc89f410feaab2cfef064ffe996ff00acb6 100644
--- a/src/interpreter/bytecode-array-builder.cc
+++ b/src/interpreter/bytecode-array-builder.cc
@@ -277,6 +277,16 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
}
+BytecodeArrayBuilder& BytecodeArrayBuilder::LoadBooleanConstant(bool value) {
+ if (value) {
+ LoadTrue();
+ } else {
+ LoadFalse();
+ }
+ return *this;
+}
+
+
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
Register reg) {
if (!IsRegisterInAccumulator(reg)) {
@@ -513,15 +523,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
bool BytecodeArrayBuilder::NeedToBooleanCast() {
- if (!LastBytecodeInSameBlock()) {
- // If the previous bytecode was from a different block return false.
- return true;
- }
-
- // If the previous bytecode puts a boolean in the accumulator return true.
- switch (Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_))) {
+ switch (GetPreviousBytecodeInSameBlock()) {
case Bytecode::kToBoolean:
UNREACHABLE();
+ // If the previous bytecode puts a boolean in the accumulator return true.
case Bytecode::kLdaTrue:
case Bytecode::kLdaFalse:
case Bytecode::kLogicalNot:
@@ -537,6 +542,8 @@ bool BytecodeArrayBuilder::NeedToBooleanCast() {
case Bytecode::kTestIn:
case Bytecode::kForInDone:
return false;
+ // Also handles the case where the previous bytecode was in a different
+ // block.
default:
return true;
}
@@ -547,7 +554,24 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() {
// If the previous bytecode puts a boolean in the accumulator
// there is no need to emit an instruction.
if (NeedToBooleanCast()) {
- Output(Bytecode::kToBoolean);
+ switch (GetPreviousBytecodeInSameBlock()) {
+ // If the previous bytecode is a constant evaluate it and return false.
+ case Bytecode::kLdaZero: {
+ LoadFalse();
+ break;
+ }
+ case Bytecode::kLdaSmi8: {
+ LoadBooleanConstant(GetRawOperand(0) != 0);
+ break;
+ }
+ case Bytecode::kLdaConstant: {
+ Handle<Object> object = GetConstantForIndexOperand(0);
+ LoadBooleanConstant(object->BooleanValue());
+ break;
+ }
+ default:
+ Output(Bytecode::kToBoolean);
+ }
}
return *this;
}
@@ -560,6 +584,20 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
+ Bytecode prev_bytecode = GetPreviousBytecodeInSameBlock();
+ switch (prev_bytecode) {
+ case Bytecode::kLdaConstantWide:
+ case Bytecode::kLdaConstant: {
+ Handle<Object> object = GetConstantForIndexOperand(0);
+ if (object->IsName()) return *this;
+ break;
+ }
+ case Bytecode::kToName:
+ case Bytecode::kTypeOf:
+ return *this;
+ default:
+ break;
+ }
Output(Bytecode::kToName);
return *this;
}
@@ -990,15 +1028,49 @@ bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
}
+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
+ // Returns the previous bytecode in the same basicblock. If there is none it
+ // returns Bytecode::kLast.
+ if (!LastBytecodeInSameBlock()) {
+ return Bytecode::kLast;
+ }
+ return Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_));
+}
+
+
+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
+ Bytecode bytecode = GetPreviousBytecodeInSameBlock();
+ DCHECK_GE(operand_index, 0);
+ DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode));
+ size_t operand_offset = last_bytecode_start_ +
+ Bytecodes::GetOperandOffset(bytecode, operand_index);
+ OperandSize size = Bytecodes::GetOperandSize(GetPreviousBytecodeInSameBlock(),
+ operand_index);
+ switch (size) {
+ default:
+ case OperandSize::kNone:
+ UNREACHABLE();
+ case OperandSize::kByte:
+ return static_cast<uint32_t>(bytecodes()->at(operand_offset));
+ case OperandSize::kShort:
+ uint16_t operand = (bytecodes()->at(operand_offset) << 8) +
+ bytecodes()->at(operand_offset + 1);
+ return static_cast<uint32_t>(operand);
+ }
+}
+
+
+Handle<Object> BytecodeArrayBuilder::GetConstantForIndexOperand(
oth 2015/11/23 13:46:41 GetConstantForIndexOperandOfPreviousBytecode(). Ph
+ int operand_index) {
+ return constants_.at(GetRawOperand(operand_index));
+}
+
+
bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
- if (!LastBytecodeInSameBlock()) return false;
- Bytecode previous_bytecode =
- Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_));
+ Bytecode previous_bytecode = GetPreviousBytecodeInSameBlock();
if (previous_bytecode == Bytecode::kLdar ||
previous_bytecode == Bytecode::kStar) {
- size_t operand_offset = last_bytecode_start_ +
- Bytecodes::GetOperandOffset(previous_bytecode, 0);
- if (reg == Register::FromOperand(bytecodes()->at(operand_offset))) {
+ if (reg == Register::FromOperand(GetRawOperand(0))) {
return true;
}
}

Powered by Google App Engine
This is Rietveld 408576698