| Index: src/interpreter/bytecode-array-builder.cc
|
| diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc
|
| index 594d8faa25e02dec182eae96e94f802eaa01dd58..7f0fe60c4453a737df5511b95d620d4f14e81d2c 100644
|
| --- a/src/interpreter/bytecode-array-builder.cc
|
| +++ b/src/interpreter/bytecode-array-builder.cc
|
| @@ -11,24 +11,29 @@ namespace interpreter {
|
| class BytecodeArrayBuilder::PreviousBytecodeHelper {
|
| public:
|
| explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder)
|
| - : array_builder_(array_builder) {}
|
| + : array_builder_(array_builder),
|
| + previous_bytecode_start_(array_builder_.last_bytecode_start_) {
|
| + // This helper is expected to be instantiated only when the last bytecode is
|
| + // in the same basic block.
|
| + DCHECK(array_builder_.LastBytecodeInSameBlock());
|
| + }
|
|
|
| - 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;
|
| - }
|
| + // Returns the previous bytecode in the same basic block.
|
| + MUST_USE_RESULT Bytecode GetBytecode() const {
|
| + DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_);
|
| return Bytecodes::FromByte(
|
| - array_builder_.bytecodes()->at(array_builder_.last_bytecode_start_));
|
| + array_builder_.bytecodes()->at(previous_bytecode_start_));
|
| }
|
|
|
| - uint32_t GetOperand(int operand_index) const {
|
| + // Returns the operand at operand_index for the previous bytecode in the
|
| + // same basic block.
|
| + MUST_USE_RESULT uint32_t GetOperand(int operand_index) const {
|
| + DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_);
|
| Bytecode bytecode = GetBytecode();
|
| DCHECK_GE(operand_index, 0);
|
| DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode));
|
| size_t operand_offset =
|
| - array_builder_.last_bytecode_start_ +
|
| + previous_bytecode_start_ +
|
| Bytecodes::GetOperandOffset(bytecode, operand_index);
|
| OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index);
|
| switch (size) {
|
| @@ -52,6 +57,9 @@ class BytecodeArrayBuilder::PreviousBytecodeHelper {
|
|
|
| private:
|
| const BytecodeArrayBuilder& array_builder_;
|
| + size_t previous_bytecode_start_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper);
|
| };
|
|
|
|
|
| @@ -580,6 +588,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
|
|
|
|
|
| bool BytecodeArrayBuilder::NeedToBooleanCast() {
|
| + if (!LastBytecodeInSameBlock()) {
|
| + return true;
|
| + }
|
| PreviousBytecodeHelper previous_bytecode(*this);
|
| switch (previous_bytecode.GetBytecode()) {
|
| case Bytecode::kToBoolean:
|
| @@ -600,8 +611,6 @@ 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;
|
| }
|
| @@ -609,10 +618,14 @@ bool BytecodeArrayBuilder::NeedToBooleanCast() {
|
|
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() {
|
| - PreviousBytecodeHelper previous_bytecode(*this);
|
| + if (!LastBytecodeInSameBlock()) {
|
| + Output(Bytecode::kToBoolean);
|
| + return *this;
|
| + }
|
| // If the previous bytecode puts a boolean in the accumulator
|
| // there is no need to emit an instruction.
|
| if (NeedToBooleanCast()) {
|
| + PreviousBytecodeHelper previous_bytecode(*this);
|
| switch (previous_bytecode.GetBytecode()) {
|
| // If the previous bytecode is a constant evaluate it and return false.
|
| case Bytecode::kLdaZero: {
|
| @@ -643,19 +656,21 @@ 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;
|
| + if (LastBytecodeInSameBlock()) {
|
| + PreviousBytecodeHelper previous_bytecode(*this);
|
| + switch (previous_bytecode.GetBytecode()) {
|
| + case Bytecode::kToName:
|
| + case Bytecode::kTypeOf:
|
| + return *this;
|
| + case Bytecode::kLdaConstantWide:
|
| + case Bytecode::kLdaConstant: {
|
| + Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
|
| + if (object->IsName()) return *this;
|
| + break;
|
| + }
|
| + default:
|
| + break;
|
| }
|
| - case Bytecode::kToName:
|
| - case Bytecode::kTypeOf:
|
| - return *this;
|
| - default:
|
| - break;
|
| }
|
| Output(Bytecode::kToName);
|
| return *this;
|
| @@ -1089,10 +1104,11 @@ bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
|
|
|
|
|
| bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
|
| - PreviousBytecodeHelper previous_bytecode(*this);
|
| - if (previous_bytecode.GetBytecode() == Bytecode::kLdar ||
|
| - previous_bytecode.GetBytecode() == Bytecode::kStar) {
|
| - if (reg == Register::FromOperand(previous_bytecode.GetOperand(0))) {
|
| + if (LastBytecodeInSameBlock()) {
|
| + PreviousBytecodeHelper previous_bytecode(*this);
|
| + Bytecode bytecode = previous_bytecode.GetBytecode();
|
| + if ((bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) &&
|
| + (reg == Register::FromOperand(previous_bytecode.GetOperand(0)))) {
|
| return true;
|
| }
|
| }
|
|
|