| Index: src/interpreter/bytecode-peephole-optimizer.cc
|
| diff --git a/src/interpreter/bytecode-peephole-optimizer.cc b/src/interpreter/bytecode-peephole-optimizer.cc
|
| index 0f18d1b8c1053a1a3dd7f51cef53c9f2ea34453b..790b270abddf3cccb90ba3a6b834c1a87795891f 100644
|
| --- a/src/interpreter/bytecode-peephole-optimizer.cc
|
| +++ b/src/interpreter/bytecode-peephole-optimizer.cc
|
| @@ -15,67 +15,67 @@ namespace interpreter {
|
| BytecodePeepholeOptimizer::BytecodePeepholeOptimizer(
|
| ConstantArrayBuilder* constant_array_builder,
|
| BytecodePipelineStage* next_stage)
|
| - : constant_array_builder_(constant_array_builder),
|
| - next_stage_(next_stage),
|
| - last_is_discardable_(false) {
|
| + : constant_array_builder_(constant_array_builder), next_stage_(next_stage) {
|
| InvalidateLast();
|
| }
|
|
|
| -void BytecodePeepholeOptimizer::InvalidateLast() {
|
| - last_.set_bytecode(Bytecode::kIllegal);
|
| +// override
|
| +Handle<BytecodeArray> BytecodePeepholeOptimizer::ToBytecodeArray(
|
| + int fixed_register_count, int parameter_count,
|
| + Handle<FixedArray> handler_table) {
|
| + Flush();
|
| + return next_stage_->ToBytecodeArray(fixed_register_count, parameter_count,
|
| + handler_table);
|
| }
|
|
|
| -bool BytecodePeepholeOptimizer::LastIsValid() const {
|
| - return last_.bytecode() != Bytecode::kIllegal;
|
| +// override
|
| +void BytecodePeepholeOptimizer::Write(BytecodeNode* node) {
|
| + node = OptimizeAndEmitLast(node);
|
| + if (node != nullptr) {
|
| + SetLast(node);
|
| + }
|
| }
|
|
|
| -void BytecodePeepholeOptimizer::SetLast(const BytecodeNode* const node) {
|
| - last_.Clone(node);
|
| - last_is_discardable_ = true;
|
| +// override
|
| +void BytecodePeepholeOptimizer::WriteJump(BytecodeNode* node,
|
| + BytecodeLabel* label) {
|
| + node = OptimizeAndEmitLast(node);
|
| + next_stage_->WriteJump(node, label);
|
| }
|
|
|
| // override
|
| -size_t BytecodePeepholeOptimizer::FlushForOffset() {
|
| - size_t buffered_size = next_stage_->FlushForOffset();
|
| - if (LastIsValid()) {
|
| - if (last_.bytecode() == Bytecode::kNop &&
|
| - !last_.source_info().is_statement()) {
|
| - // The Nop can be dropped as it doesn't have a statement
|
| - // position for the debugger and doesn't have any effects by
|
| - // definition.
|
| - InvalidateLast();
|
| - } else {
|
| - buffered_size += last_.Size();
|
| - last_is_discardable_ = false;
|
| - }
|
| - }
|
| - return buffered_size;
|
| +void BytecodePeepholeOptimizer::BindLabel(BytecodeLabel* label) {
|
| + Flush();
|
| + next_stage_->BindLabel(label);
|
| }
|
|
|
| // override
|
| -void BytecodePeepholeOptimizer::FlushBasicBlock() {
|
| +void BytecodePeepholeOptimizer::BindLabel(const BytecodeLabel& target,
|
| + BytecodeLabel* label) {
|
| + // There is no need to flush here, it will have been flushed when |target|
|
| + // was bound.
|
| + next_stage_->BindLabel(target, label);
|
| +}
|
| +
|
| +void BytecodePeepholeOptimizer::Flush() {
|
| + // TODO(oth/rmcilroy): We could check CanElideLast() here to potentially
|
| + // eliminate last rather than writing it.
|
| if (LastIsValid()) {
|
| next_stage_->Write(&last_);
|
| InvalidateLast();
|
| }
|
| - next_stage_->FlushBasicBlock();
|
| }
|
|
|
| -// override
|
| -void BytecodePeepholeOptimizer::Write(BytecodeNode* node) {
|
| - // Attempt optimization if there is an earlier node to optimize with.
|
| - if (LastIsValid()) {
|
| - node = Optimize(node);
|
| - // Only output the last node if it wasn't invalidated by the optimization.
|
| - if (LastIsValid()) {
|
| - next_stage_->Write(&last_);
|
| - InvalidateLast();
|
| - }
|
| - }
|
| +void BytecodePeepholeOptimizer::InvalidateLast() {
|
| + last_.set_bytecode(Bytecode::kIllegal);
|
| +}
|
|
|
| - if (node != nullptr) {
|
| - SetLast(node);
|
| - }
|
| +bool BytecodePeepholeOptimizer::LastIsValid() const {
|
| + return last_.bytecode() != Bytecode::kIllegal;
|
| +}
|
| +
|
| +void BytecodePeepholeOptimizer::SetLast(const BytecodeNode* const node) {
|
| + last_.Clone(node);
|
| }
|
|
|
| Handle<Object> BytecodePeepholeOptimizer::GetConstantForIndexOperand(
|
| @@ -260,10 +260,6 @@ bool BytecodePeepholeOptimizer::TransformLastAndCurrentBytecodes(
|
|
|
| bool BytecodePeepholeOptimizer::CanElideLast(
|
| const BytecodeNode* const current) const {
|
| - if (!last_is_discardable_) {
|
| - return false;
|
| - }
|
| -
|
| if (last_.bytecode() == Bytecode::kNop) {
|
| // Nop are placeholders for holding source position information.
|
| return true;
|
| @@ -311,6 +307,20 @@ BytecodeNode* BytecodePeepholeOptimizer::Optimize(BytecodeNode* current) {
|
| return current;
|
| }
|
|
|
| +BytecodeNode* BytecodePeepholeOptimizer::OptimizeAndEmitLast(
|
| + BytecodeNode* current) {
|
| + // Attempt optimization if there is an earlier node to optimize with.
|
| + if (LastIsValid()) {
|
| + current = Optimize(current);
|
| + // Only output the last node if it wasn't invalidated by the optimization.
|
| + if (LastIsValid()) {
|
| + next_stage_->Write(&last_);
|
| + InvalidateLast();
|
| + }
|
| + }
|
| + return current;
|
| +}
|
| +
|
| } // namespace interpreter
|
| } // namespace internal
|
| } // namespace v8
|
|
|