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

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: rebased the patch and removed unused definitions of matcher classes in unittests 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
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/bytecode-array-builder.cc
diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc
index f7efb103063c921ab10dd8bbea7296065ef63452..594d8faa25e02dec182eae96e94f802eaa01dd58 100644
--- a/src/interpreter/bytecode-array-builder.cc
+++ b/src/interpreter/bytecode-array-builder.cc
@@ -8,6 +8,53 @@ namespace v8 {
namespace internal {
namespace interpreter {
+class BytecodeArrayBuilder::PreviousBytecodeHelper {
+ public:
+ explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder)
+ : array_builder_(array_builder) {}
+
+ Bytecode GetBytecode() const {
+ // Returns the previous bytecode in the same basicblock. If there is none it
+ // returns Bytecode::kLast.
+ if (!array_builder_.LastBytecodeInSameBlock()) {
+ return Bytecode::kLast;
rmcilroy 2015/12/07 11:56:03 Bytecode::kLast is the same as the last valid byte
+ }
+ return Bytecodes::FromByte(
+ array_builder_.bytecodes()->at(array_builder_.last_bytecode_start_));
+ }
+
+ uint32_t GetOperand(int operand_index) const {
+ Bytecode bytecode = GetBytecode();
+ DCHECK_GE(operand_index, 0);
+ DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode));
+ size_t operand_offset =
+ array_builder_.last_bytecode_start_ +
+ Bytecodes::GetOperandOffset(bytecode, operand_index);
+ OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index);
+ switch (size) {
+ default:
+ case OperandSize::kNone:
+ UNREACHABLE();
+ case OperandSize::kByte:
+ return static_cast<uint32_t>(
+ array_builder_.bytecodes()->at(operand_offset));
+ case OperandSize::kShort:
+ uint16_t operand =
+ (array_builder_.bytecodes()->at(operand_offset) << 8) +
+ array_builder_.bytecodes()->at(operand_offset + 1);
+ return static_cast<uint32_t>(operand);
+ }
+ }
+
+ Handle<Object> GetConstantForIndexOperand(int operand_index) const {
+ return array_builder_.constants_.at(GetOperand(operand_index));
+ }
+
+ private:
+ const BytecodeArrayBuilder& array_builder_;
+};
+
+
BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone)
: isolate_(isolate),
zone_(zone),
@@ -277,6 +324,16 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
}
+BytecodeArrayBuilder& BytecodeArrayBuilder::LoadBooleanConstant(bool value) {
+ if (value) {
+ LoadTrue();
+ } else {
+ LoadFalse();
+ }
+ return *this;
+}
+
+
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
Register reg) {
if (!IsRegisterInAccumulator(reg)) {
@@ -523,15 +580,11 @@ 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_))) {
+ PreviousBytecodeHelper previous_bytecode(*this);
+ switch (previous_bytecode.GetBytecode()) {
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:
@@ -547,6 +600,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;
}
@@ -554,10 +609,28 @@ bool BytecodeArrayBuilder::NeedToBooleanCast() {
BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() {
+ PreviousBytecodeHelper previous_bytecode(*this);
// If the previous bytecode puts a boolean in the accumulator
// there is no need to emit an instruction.
if (NeedToBooleanCast()) {
- Output(Bytecode::kToBoolean);
+ switch (previous_bytecode.GetBytecode()) {
rmcilroy 2015/12/07 11:56:03 Optional nit - It would be nice to have some tests
+ // If the previous bytecode is a constant evaluate it and return false.
+ case Bytecode::kLdaZero: {
+ LoadFalse();
+ break;
+ }
+ case Bytecode::kLdaSmi8: {
+ LoadBooleanConstant(previous_bytecode.GetOperand(0) != 0);
+ break;
+ }
+ case Bytecode::kLdaConstant: {
+ Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
+ LoadBooleanConstant(object->BooleanValue());
+ break;
+ }
+ default:
+ Output(Bytecode::kToBoolean);
+ }
}
return *this;
}
@@ -570,6 +643,20 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
+ PreviousBytecodeHelper previous_bytecode(*this);
+ switch (previous_bytecode.GetBytecode()) {
+ case Bytecode::kLdaConstantWide:
+ case Bytecode::kLdaConstant: {
+ Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
+ if (object->IsName()) return *this;
+ break;
+ }
+ case Bytecode::kToName:
+ case Bytecode::kTypeOf:
+ return *this;
+ default:
+ break;
+ }
Output(Bytecode::kToName);
return *this;
}
@@ -1002,14 +1089,10 @@ bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
- if (!LastBytecodeInSameBlock()) return false;
- Bytecode previous_bytecode =
- Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_));
- 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))) {
+ PreviousBytecodeHelper previous_bytecode(*this);
+ if (previous_bytecode.GetBytecode() == Bytecode::kLdar ||
+ previous_bytecode.GetBytecode() == Bytecode::kStar) {
+ if (reg == Register::FromOperand(previous_bytecode.GetOperand(0))) {
return true;
}
}
« 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