From 85eff14c373e529d268945f9725af5b4350074e9 Mon Sep 17 00:00:00 2001 From: yangguo Date: Fri, 5 Feb 2016 05:29:03 -0800 Subject: [PATCH] [interpreter] source positions should not be emitted for dead code. R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/1668863002 Cr-Commit-Position: refs/heads/master@{#33775} --- src/interpreter/bytecode-array-builder.cc | 23 ++++++++++++------ src/interpreter/source-position-table.cc | 24 ++++++++++++++----- src/interpreter/source-position-table.h | 5 ++-- .../ignition/dead-code-source-position.js | 9 +++++++ 4 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 test/mjsunit/ignition/dead-code-source-position.js diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc index 9795b08357..7d8089b90b 100644 --- a/src/interpreter/bytecode-array-builder.cc +++ b/src/interpreter/bytecode-array-builder.cc @@ -138,7 +138,10 @@ Handle BytecodeArrayBuilder::ToBytecodeArray() { template void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { // Don't output dead code. - if (exit_seen_in_block_) return; + if (exit_seen_in_block_) { + source_position_table_builder_.RevertPosition(bytecodes()->size()); + return; + } int operand_count = static_cast(N); DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count); @@ -206,7 +209,10 @@ void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { void BytecodeArrayBuilder::Output(Bytecode bytecode) { // Don't output dead code. - if (exit_seen_in_block_) return; + if (exit_seen_in_block_) { + source_position_table_builder_.RevertPosition(bytecodes()->size()); + return; + } DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); last_bytecode_start_ = bytecodes()->size(); @@ -886,7 +892,10 @@ void BytecodeArrayBuilder::PatchJump( BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, BytecodeLabel* label) { // Don't emit dead code. - if (exit_seen_in_block_) return *this; + if (exit_seen_in_block_) { + source_position_table_builder_.RevertPosition(bytecodes()->size()); + return *this; + } // Check if the value in accumulator is boolean, if not choose an // appropriate JumpIfToBoolean bytecode. @@ -1210,14 +1219,14 @@ size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle object) { void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { if (stmt->position() == RelocInfo::kNoPosition) return; - source_position_table_builder_.AddStatementPosition( - static_cast(bytecodes_.size()), stmt->position()); + source_position_table_builder_.AddStatementPosition(bytecodes_.size(), + stmt->position()); } void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { if (expr->position() == RelocInfo::kNoPosition) return; - source_position_table_builder_.AddExpressionPosition( - static_cast(bytecodes_.size()), expr->position()); + source_position_table_builder_.AddExpressionPosition(bytecodes_.size(), + expr->position()); } bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { diff --git a/src/interpreter/source-position-table.cc b/src/interpreter/source-position-table.cc index f408f159db..b82f608ac4 100644 --- a/src/interpreter/source-position-table.cc +++ b/src/interpreter/source-position-table.cc @@ -15,20 +15,32 @@ namespace interpreter { class IsStatementField : public BitField {}; class SourcePositionField : public BitField {}; -void SourcePositionTableBuilder::AddStatementPosition(int bytecode_offset, +void SourcePositionTableBuilder::AddStatementPosition(size_t bytecode_offset, int source_position) { - AssertMonotonic(bytecode_offset); + int offset = static_cast(bytecode_offset); + AssertMonotonic(offset); uint32_t encoded = IsStatementField::encode(true) | SourcePositionField::encode(source_position); - entries_.push_back({bytecode_offset, encoded}); + entries_.push_back({offset, encoded}); } -void SourcePositionTableBuilder::AddExpressionPosition(int bytecode_offset, +void SourcePositionTableBuilder::AddExpressionPosition(size_t bytecode_offset, int source_position) { - AssertMonotonic(bytecode_offset); + int offset = static_cast(bytecode_offset); + AssertMonotonic(offset); uint32_t encoded = IsStatementField::encode(false) | SourcePositionField::encode(source_position); - entries_.push_back({bytecode_offset, encoded}); + entries_.push_back({offset, encoded}); +} + +void SourcePositionTableBuilder::RevertPosition(size_t bytecode_offset) { + int offset = static_cast(bytecode_offset); + // If we already added a source position table entry, but the bytecode array + // builder ended up not outputting a bytecode for the corresponding bytecode + // offset, we have to remove that entry. + if (entries_.size() > 0 && entries_.back().bytecode_offset == offset) { + entries_.pop_back(); + } } Handle SourcePositionTableBuilder::ToFixedArray() { diff --git a/src/interpreter/source-position-table.h b/src/interpreter/source-position-table.h index f05c0f7de5..933fb41e7b 100644 --- a/src/interpreter/source-position-table.h +++ b/src/interpreter/source-position-table.h @@ -24,8 +24,9 @@ class SourcePositionTableBuilder { explicit SourcePositionTableBuilder(Isolate* isolate, Zone* zone) : isolate_(isolate), entries_(zone) {} - void AddStatementPosition(int bytecode_offset, int source_position); - void AddExpressionPosition(int bytecode_offset, int source_position); + void AddStatementPosition(size_t bytecode_offset, int source_position); + void AddExpressionPosition(size_t bytecode_offset, int source_position); + void RevertPosition(size_t bytecode_offset); Handle ToFixedArray(); private: diff --git a/test/mjsunit/ignition/dead-code-source-position.js b/test/mjsunit/ignition/dead-code-source-position.js new file mode 100644 index 0000000000..95bb9183b8 --- /dev/null +++ b/test/mjsunit/ignition/dead-code-source-position.js @@ -0,0 +1,9 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function f() { + for (f(x) in []) { f(new f()) } +} + +f();