[Interpreter] Remove BytecodePipeline.
The BytecodePipeline is no longer used by any optimizers, so remove it and connect the BytecodeArrayBuilder directly to the BytecodeWriter. Also remove some functions from BytecodeNode which are no longer used. BUG=v8:6194 Change-Id: Id2ec94ff1d4db41b108a778100459283fbb2256c Reviewed-on: https://chromium-review.googlesource.com/471528 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Ross McIlroy <rmcilroy@chromium.org> Cr-Commit-Position: refs/heads/master@{#44619}
This commit is contained in:
parent
79bce3d655
commit
b7a7096668
6
BUILD.gn
6
BUILD.gn
@ -1635,15 +1635,17 @@ v8_source_set("v8_base") {
|
||||
"src/interpreter/bytecode-generator.h",
|
||||
"src/interpreter/bytecode-label.cc",
|
||||
"src/interpreter/bytecode-label.h",
|
||||
"src/interpreter/bytecode-node.cc",
|
||||
"src/interpreter/bytecode-node.h",
|
||||
"src/interpreter/bytecode-operands.cc",
|
||||
"src/interpreter/bytecode-operands.h",
|
||||
"src/interpreter/bytecode-pipeline.cc",
|
||||
"src/interpreter/bytecode-pipeline.h",
|
||||
"src/interpreter/bytecode-register-allocator.h",
|
||||
"src/interpreter/bytecode-register-optimizer.cc",
|
||||
"src/interpreter/bytecode-register-optimizer.h",
|
||||
"src/interpreter/bytecode-register.cc",
|
||||
"src/interpreter/bytecode-register.h",
|
||||
"src/interpreter/bytecode-source-info.cc",
|
||||
"src/interpreter/bytecode-source-info.h",
|
||||
"src/interpreter/bytecode-traits.h",
|
||||
"src/interpreter/bytecodes.cc",
|
||||
"src/interpreter/bytecodes.h",
|
||||
|
@ -7,7 +7,9 @@
|
||||
#include "src/globals.h"
|
||||
#include "src/interpreter/bytecode-array-writer.h"
|
||||
#include "src/interpreter/bytecode-label.h"
|
||||
#include "src/interpreter/bytecode-node.h"
|
||||
#include "src/interpreter/bytecode-register-optimizer.h"
|
||||
#include "src/interpreter/bytecode-source-info.h"
|
||||
#include "src/interpreter/interpreter-intrinsics.h"
|
||||
#include "src/objects-inl.h"
|
||||
|
||||
@ -50,7 +52,6 @@ BytecodeArrayBuilder::BytecodeArrayBuilder(
|
||||
register_allocator_(fixed_register_count()),
|
||||
bytecode_array_writer_(zone, &constant_array_builder_,
|
||||
source_position_mode),
|
||||
pipeline_(&bytecode_array_writer_),
|
||||
register_optimizer_(nullptr) {
|
||||
DCHECK_GE(parameter_count_, 0);
|
||||
DCHECK_GE(context_register_count_, 0);
|
||||
@ -106,8 +107,8 @@ Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) {
|
||||
|
||||
Handle<FixedArray> handler_table =
|
||||
handler_table_builder()->ToHandlerTable(isolate);
|
||||
return pipeline_->ToBytecodeArray(isolate, register_count, parameter_count(),
|
||||
handler_table);
|
||||
return bytecode_array_writer_.ToBytecodeArray(
|
||||
isolate, register_count, parameter_count(), handler_table);
|
||||
}
|
||||
|
||||
BytecodeSourceInfo BytecodeArrayBuilder::CurrentSourcePosition(
|
||||
@ -134,7 +135,7 @@ void BytecodeArrayBuilder::SetDeferredSourceInfo(
|
||||
if (deferred_source_info_.is_valid()) {
|
||||
// Emit any previous deferred source info now as a nop.
|
||||
BytecodeNode node = BytecodeNode::Nop(deferred_source_info_);
|
||||
pipeline()->Write(&node);
|
||||
bytecode_array_writer_.Write(&node);
|
||||
}
|
||||
deferred_source_info_ = source_info;
|
||||
}
|
||||
@ -146,19 +147,19 @@ void BytecodeArrayBuilder::AttachOrEmitDeferredSourceInfo(BytecodeNode* node) {
|
||||
node->set_source_info(deferred_source_info_);
|
||||
} else {
|
||||
BytecodeNode node = BytecodeNode::Nop(deferred_source_info_);
|
||||
pipeline()->Write(&node);
|
||||
bytecode_array_writer_.Write(&node);
|
||||
}
|
||||
deferred_source_info_.set_invalid();
|
||||
}
|
||||
|
||||
void BytecodeArrayBuilder::Write(BytecodeNode* node) {
|
||||
AttachOrEmitDeferredSourceInfo(node);
|
||||
pipeline()->Write(node);
|
||||
bytecode_array_writer_.Write(node);
|
||||
}
|
||||
|
||||
void BytecodeArrayBuilder::WriteJump(BytecodeNode* node, BytecodeLabel* label) {
|
||||
AttachOrEmitDeferredSourceInfo(node);
|
||||
pipeline()->WriteJump(node, label);
|
||||
bytecode_array_writer_.WriteJump(node, label);
|
||||
}
|
||||
|
||||
void BytecodeArrayBuilder::OutputLdarRaw(Register reg) {
|
||||
@ -995,14 +996,14 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) {
|
||||
// Flush the register optimizer when binding a label to ensure all
|
||||
// expected registers are valid when jumping to this label.
|
||||
if (register_optimizer_) register_optimizer_->Flush();
|
||||
pipeline_->BindLabel(label);
|
||||
bytecode_array_writer_.BindLabel(label);
|
||||
LeaveBasicBlock();
|
||||
return *this;
|
||||
}
|
||||
|
||||
BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
|
||||
BytecodeLabel* label) {
|
||||
pipeline_->BindLabel(target, label);
|
||||
bytecode_array_writer_.BindLabel(target, label);
|
||||
LeaveBasicBlock();
|
||||
return *this;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "src/interpreter/bytecode-flags.h"
|
||||
#include "src/interpreter/bytecode-register-allocator.h"
|
||||
#include "src/interpreter/bytecode-register.h"
|
||||
#include "src/interpreter/bytecode-source-info.h"
|
||||
#include "src/interpreter/bytecodes.h"
|
||||
#include "src/interpreter/constant-array-builder.h"
|
||||
#include "src/interpreter/handler-table-builder.h"
|
||||
@ -26,7 +27,6 @@ namespace interpreter {
|
||||
|
||||
class BytecodeLabel;
|
||||
class BytecodeNode;
|
||||
class BytecodePipelineStage;
|
||||
class BytecodeRegisterOptimizer;
|
||||
class Register;
|
||||
|
||||
@ -521,7 +521,6 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
|
||||
BytecodeArrayWriter* bytecode_array_writer() {
|
||||
return &bytecode_array_writer_;
|
||||
}
|
||||
BytecodePipelineStage* pipeline() { return pipeline_; }
|
||||
ConstantArrayBuilder* constant_array_builder() {
|
||||
return &constant_array_builder_;
|
||||
}
|
||||
@ -544,7 +543,6 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
|
||||
int return_position_;
|
||||
BytecodeRegisterAllocator register_allocator_;
|
||||
BytecodeArrayWriter bytecode_array_writer_;
|
||||
BytecodePipelineStage* pipeline_;
|
||||
BytecodeRegisterOptimizer* register_optimizer_;
|
||||
BytecodeSourceInfo latest_source_info_;
|
||||
BytecodeSourceInfo deferred_source_info_;
|
||||
|
@ -6,7 +6,9 @@
|
||||
|
||||
#include "src/api.h"
|
||||
#include "src/interpreter/bytecode-label.h"
|
||||
#include "src/interpreter/bytecode-node.h"
|
||||
#include "src/interpreter/bytecode-register.h"
|
||||
#include "src/interpreter/bytecode-source-info.h"
|
||||
#include "src/interpreter/constant-array-builder.h"
|
||||
#include "src/log.h"
|
||||
#include "src/objects-inl.h"
|
||||
@ -33,10 +35,6 @@ BytecodeArrayWriter::BytecodeArrayWriter(
|
||||
bytecodes_.reserve(512); // Derived via experimentation.
|
||||
}
|
||||
|
||||
// override
|
||||
BytecodeArrayWriter::~BytecodeArrayWriter() {}
|
||||
|
||||
// override
|
||||
Handle<BytecodeArray> BytecodeArrayWriter::ToBytecodeArray(
|
||||
Isolate* isolate, int register_count, int parameter_count,
|
||||
Handle<FixedArray> handler_table) {
|
||||
@ -57,7 +55,6 @@ Handle<BytecodeArray> BytecodeArrayWriter::ToBytecodeArray(
|
||||
return bytecode_array;
|
||||
}
|
||||
|
||||
// override
|
||||
void BytecodeArrayWriter::Write(BytecodeNode* node) {
|
||||
DCHECK(!Bytecodes::IsJump(node->bytecode()));
|
||||
|
||||
@ -69,7 +66,6 @@ void BytecodeArrayWriter::Write(BytecodeNode* node) {
|
||||
EmitBytecode(node);
|
||||
}
|
||||
|
||||
// override
|
||||
void BytecodeArrayWriter::WriteJump(BytecodeNode* node, BytecodeLabel* label) {
|
||||
DCHECK(Bytecodes::IsJump(node->bytecode()));
|
||||
|
||||
@ -83,7 +79,6 @@ void BytecodeArrayWriter::WriteJump(BytecodeNode* node, BytecodeLabel* label) {
|
||||
EmitJump(node, label);
|
||||
}
|
||||
|
||||
// override
|
||||
void BytecodeArrayWriter::BindLabel(BytecodeLabel* label) {
|
||||
size_t current_offset = bytecodes()->size();
|
||||
if (label->is_forward_target()) {
|
||||
@ -96,7 +91,6 @@ void BytecodeArrayWriter::BindLabel(BytecodeLabel* label) {
|
||||
exit_seen_in_block_ = false; // Starting a new basic block.
|
||||
}
|
||||
|
||||
// override
|
||||
void BytecodeArrayWriter::BindLabel(const BytecodeLabel& target,
|
||||
BytecodeLabel* label) {
|
||||
DCHECK(!label->is_bound());
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "src/base/compiler-specific.h"
|
||||
#include "src/globals.h"
|
||||
#include "src/interpreter/bytecode-pipeline.h"
|
||||
#include "src/interpreter/bytecodes.h"
|
||||
#include "src/source-position-table.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -18,26 +18,24 @@ class SourcePositionTableBuilder;
|
||||
namespace interpreter {
|
||||
|
||||
class BytecodeLabel;
|
||||
class BytecodeNode;
|
||||
class ConstantArrayBuilder;
|
||||
|
||||
// Class for emitting bytecode as the final stage of the bytecode
|
||||
// generation pipeline.
|
||||
class V8_EXPORT_PRIVATE BytecodeArrayWriter final
|
||||
: public NON_EXPORTED_BASE(BytecodePipelineStage) {
|
||||
class V8_EXPORT_PRIVATE BytecodeArrayWriter final {
|
||||
public:
|
||||
BytecodeArrayWriter(
|
||||
Zone* zone, ConstantArrayBuilder* constant_array_builder,
|
||||
SourcePositionTableBuilder::RecordingMode source_position_mode);
|
||||
virtual ~BytecodeArrayWriter();
|
||||
|
||||
// BytecodePipelineStage interface.
|
||||
void Write(BytecodeNode* node) override;
|
||||
void WriteJump(BytecodeNode* node, BytecodeLabel* label) override;
|
||||
void BindLabel(BytecodeLabel* label) override;
|
||||
void BindLabel(const BytecodeLabel& target, BytecodeLabel* label) override;
|
||||
Handle<BytecodeArray> ToBytecodeArray(
|
||||
Isolate* isolate, int register_count, int parameter_count,
|
||||
Handle<FixedArray> handler_table) override;
|
||||
void Write(BytecodeNode* node);
|
||||
void WriteJump(BytecodeNode* node, BytecodeLabel* label);
|
||||
void BindLabel(BytecodeLabel* label);
|
||||
void BindLabel(const BytecodeLabel& target, BytecodeLabel* label);
|
||||
Handle<BytecodeArray> ToBytecodeArray(Isolate* isolate, int register_count,
|
||||
int parameter_count,
|
||||
Handle<FixedArray> handler_table);
|
||||
|
||||
private:
|
||||
// Maximum sized packed bytecode is comprised of a prefix bytecode,
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Copyright 2017 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.
|
||||
|
||||
#include "src/interpreter/bytecode-pipeline.h"
|
||||
#include "src/interpreter/bytecode-node.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include "src/source-position-table.h"
|
||||
@ -47,14 +47,6 @@ bool BytecodeNode::operator==(const BytecodeNode& other) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const BytecodeSourceInfo& info) {
|
||||
if (info.is_valid()) {
|
||||
char description = info.is_statement() ? 'S' : 'E';
|
||||
os << info.source_position() << ' ' << description << '>';
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const BytecodeNode& node) {
|
||||
node.Print(os);
|
||||
return os;
|
@ -1,138 +1,22 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Copyright 2017 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.
|
||||
|
||||
#ifndef V8_INTERPRETER_BYTECODE_PIPELINE_H_
|
||||
#define V8_INTERPRETER_BYTECODE_PIPELINE_H_
|
||||
#ifndef V8_INTERPRETER_BYTECODE_NODE_H_
|
||||
#define V8_INTERPRETER_BYTECODE_NODE_H_
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "src/base/compiler-specific.h"
|
||||
#include "src/globals.h"
|
||||
#include "src/interpreter/bytecode-register-allocator.h"
|
||||
#include "src/interpreter/bytecode-register.h"
|
||||
#include "src/interpreter/bytecode-source-info.h"
|
||||
#include "src/interpreter/bytecodes.h"
|
||||
#include "src/objects.h"
|
||||
#include "src/zone/zone-containers.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace interpreter {
|
||||
|
||||
class BytecodeLabel;
|
||||
class BytecodeNode;
|
||||
class BytecodeSourceInfo;
|
||||
|
||||
// Interface for bytecode pipeline stages.
|
||||
class BytecodePipelineStage {
|
||||
public:
|
||||
virtual ~BytecodePipelineStage() {}
|
||||
|
||||
// Write bytecode node |node| into pipeline. The node is only valid
|
||||
// for the duration of the call. Callee's should clone it if
|
||||
// deferring Write() to the next stage.
|
||||
virtual void Write(BytecodeNode* node) = 0;
|
||||
|
||||
// Write jump bytecode node |node| which jumps to |label| into pipeline.
|
||||
// The node and label are only valid for the duration of the call. This call
|
||||
// implicitly ends the current basic block so should always write to the next
|
||||
// stage.
|
||||
virtual void WriteJump(BytecodeNode* node, BytecodeLabel* label) = 0;
|
||||
|
||||
// Binds |label| to the current bytecode location. This call implicitly
|
||||
// ends the current basic block and so any deferred bytecodes should be
|
||||
// written to the next stage.
|
||||
virtual void BindLabel(BytecodeLabel* label) = 0;
|
||||
|
||||
// Binds |label| to the location of |target|. This call implicitly
|
||||
// ends the current basic block and so any deferred bytecodes should be
|
||||
// written to the next stage.
|
||||
virtual void BindLabel(const BytecodeLabel& target, BytecodeLabel* label) = 0;
|
||||
|
||||
// Flush the pipeline and generate a bytecode array.
|
||||
virtual Handle<BytecodeArray> ToBytecodeArray(
|
||||
Isolate* isolate, int register_count, int parameter_count,
|
||||
Handle<FixedArray> handler_table) = 0;
|
||||
};
|
||||
|
||||
// Source code position information.
|
||||
class BytecodeSourceInfo final {
|
||||
public:
|
||||
static const int kUninitializedPosition = -1;
|
||||
|
||||
BytecodeSourceInfo()
|
||||
: position_type_(PositionType::kNone),
|
||||
source_position_(kUninitializedPosition) {}
|
||||
|
||||
BytecodeSourceInfo(int source_position, bool is_statement)
|
||||
: position_type_(is_statement ? PositionType::kStatement
|
||||
: PositionType::kExpression),
|
||||
source_position_(source_position) {
|
||||
DCHECK_GE(source_position, 0);
|
||||
}
|
||||
|
||||
// Makes instance into a statement position.
|
||||
void MakeStatementPosition(int source_position) {
|
||||
// Statement positions can be replaced by other statement
|
||||
// positions. For example , "for (x = 0; x < 3; ++x) 7;" has a
|
||||
// statement position associated with 7 but no bytecode associated
|
||||
// with it. Then Next is emitted after the body and has
|
||||
// statement position and overrides the existing one.
|
||||
position_type_ = PositionType::kStatement;
|
||||
source_position_ = source_position;
|
||||
}
|
||||
|
||||
// Makes instance into an expression position. Instance should not
|
||||
// be a statement position otherwise it could be lost and impair the
|
||||
// debugging experience.
|
||||
void MakeExpressionPosition(int source_position) {
|
||||
DCHECK(!is_statement());
|
||||
position_type_ = PositionType::kExpression;
|
||||
source_position_ = source_position;
|
||||
}
|
||||
|
||||
// Forces an instance into an expression position.
|
||||
void ForceExpressionPosition(int source_position) {
|
||||
position_type_ = PositionType::kExpression;
|
||||
source_position_ = source_position;
|
||||
}
|
||||
|
||||
int source_position() const {
|
||||
DCHECK(is_valid());
|
||||
return source_position_;
|
||||
}
|
||||
|
||||
bool is_statement() const {
|
||||
return position_type_ == PositionType::kStatement;
|
||||
}
|
||||
bool is_expression() const {
|
||||
return position_type_ == PositionType::kExpression;
|
||||
}
|
||||
|
||||
bool is_valid() const { return position_type_ != PositionType::kNone; }
|
||||
void set_invalid() {
|
||||
position_type_ = PositionType::kNone;
|
||||
source_position_ = kUninitializedPosition;
|
||||
}
|
||||
|
||||
bool operator==(const BytecodeSourceInfo& other) const {
|
||||
return position_type_ == other.position_type_ &&
|
||||
source_position_ == other.source_position_;
|
||||
}
|
||||
|
||||
bool operator!=(const BytecodeSourceInfo& other) const {
|
||||
return position_type_ != other.position_type_ ||
|
||||
source_position_ != other.source_position_;
|
||||
}
|
||||
|
||||
private:
|
||||
enum class PositionType : uint8_t { kNone, kExpression, kStatement };
|
||||
|
||||
PositionType position_type_;
|
||||
int source_position_;
|
||||
};
|
||||
|
||||
// A container for a generated bytecode, it's operands, and source information.
|
||||
// These must be allocated by a BytecodeNodeAllocator instance.
|
||||
class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) {
|
||||
class V8_EXPORT_PRIVATE BytecodeNode final {
|
||||
public:
|
||||
INLINE(BytecodeNode(Bytecode bytecode,
|
||||
BytecodeSourceInfo source_info = BytecodeSourceInfo()))
|
||||
@ -215,39 +99,9 @@ class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) {
|
||||
BYTECODE_LIST(DEFINE_BYTECODE_NODE_CREATOR)
|
||||
#undef DEFINE_BYTECODE_NODE_CREATOR
|
||||
|
||||
// Replace the bytecode of this node with |bytecode| and keep the operands.
|
||||
void replace_bytecode(Bytecode bytecode) {
|
||||
DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode_),
|
||||
Bytecodes::NumberOfOperands(bytecode));
|
||||
bytecode_ = bytecode;
|
||||
}
|
||||
|
||||
void update_operand0(uint32_t operand0) { SetOperand(0, operand0); }
|
||||
|
||||
// Print to stream |os|.
|
||||
void Print(std::ostream& os) const;
|
||||
|
||||
// Transform to a node representing |new_bytecode| which has one
|
||||
// operand more than the current bytecode.
|
||||
void Transform(Bytecode new_bytecode, uint32_t extra_operand) {
|
||||
DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode),
|
||||
Bytecodes::NumberOfOperands(bytecode()) + 1);
|
||||
DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 ||
|
||||
Bytecodes::GetOperandType(new_bytecode, 0) ==
|
||||
Bytecodes::GetOperandType(bytecode(), 0));
|
||||
DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 2 ||
|
||||
Bytecodes::GetOperandType(new_bytecode, 1) ==
|
||||
Bytecodes::GetOperandType(bytecode(), 1));
|
||||
DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 3 ||
|
||||
Bytecodes::GetOperandType(new_bytecode, 2) ==
|
||||
Bytecodes::GetOperandType(bytecode(), 2));
|
||||
DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 4);
|
||||
|
||||
bytecode_ = new_bytecode;
|
||||
operand_count_++;
|
||||
SetOperand(operand_count() - 1, extra_operand);
|
||||
}
|
||||
|
||||
Bytecode bytecode() const { return bytecode_; }
|
||||
|
||||
uint32_t operand(int i) const {
|
||||
@ -256,6 +110,8 @@ class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) {
|
||||
}
|
||||
const uint32_t* operands() const { return operands_; }
|
||||
|
||||
void update_operand0(uint32_t operand0) { SetOperand(0, operand0); }
|
||||
|
||||
int operand_count() const { return operand_count_; }
|
||||
OperandScale operand_scale() const { return operand_scale_; }
|
||||
|
||||
@ -409,8 +265,6 @@ class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) {
|
||||
BytecodeSourceInfo source_info_;
|
||||
};
|
||||
|
||||
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
|
||||
const BytecodeSourceInfo& info);
|
||||
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
|
||||
const BytecodeNode& node);
|
||||
|
||||
@ -418,4 +272,4 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_INTERPRETER_BYTECODE_PIPELINE_H_
|
||||
#endif // V8_INTERPRETER_BYTECODE_NODE_H_
|
24
src/interpreter/bytecode-source-info.cc
Normal file
24
src/interpreter/bytecode-source-info.cc
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
#include "src/interpreter/bytecode-source-info.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include "src/source-position-table.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace interpreter {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const BytecodeSourceInfo& info) {
|
||||
if (info.is_valid()) {
|
||||
char description = info.is_statement() ? 'S' : 'E';
|
||||
os << info.source_position() << ' ' << description << '>';
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace interpreter
|
||||
} // namespace internal
|
||||
} // namespace v8
|
98
src/interpreter/bytecode-source-info.h
Normal file
98
src/interpreter/bytecode-source-info.h
Normal file
@ -0,0 +1,98 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
#ifndef V8_INTERPRETER_BYTECODE_SOURCE_INFO_H_
|
||||
#define V8_INTERPRETER_BYTECODE_SOURCE_INFO_H_
|
||||
|
||||
#include "src/globals.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace interpreter {
|
||||
|
||||
// Source code position information.
|
||||
class BytecodeSourceInfo final {
|
||||
public:
|
||||
static const int kUninitializedPosition = -1;
|
||||
|
||||
BytecodeSourceInfo()
|
||||
: position_type_(PositionType::kNone),
|
||||
source_position_(kUninitializedPosition) {}
|
||||
|
||||
BytecodeSourceInfo(int source_position, bool is_statement)
|
||||
: position_type_(is_statement ? PositionType::kStatement
|
||||
: PositionType::kExpression),
|
||||
source_position_(source_position) {
|
||||
DCHECK_GE(source_position, 0);
|
||||
}
|
||||
|
||||
// Makes instance into a statement position.
|
||||
void MakeStatementPosition(int source_position) {
|
||||
// Statement positions can be replaced by other statement
|
||||
// positions. For example , "for (x = 0; x < 3; ++x) 7;" has a
|
||||
// statement position associated with 7 but no bytecode associated
|
||||
// with it. Then Next is emitted after the body and has
|
||||
// statement position and overrides the existing one.
|
||||
position_type_ = PositionType::kStatement;
|
||||
source_position_ = source_position;
|
||||
}
|
||||
|
||||
// Makes instance into an expression position. Instance should not
|
||||
// be a statement position otherwise it could be lost and impair the
|
||||
// debugging experience.
|
||||
void MakeExpressionPosition(int source_position) {
|
||||
DCHECK(!is_statement());
|
||||
position_type_ = PositionType::kExpression;
|
||||
source_position_ = source_position;
|
||||
}
|
||||
|
||||
// Forces an instance into an expression position.
|
||||
void ForceExpressionPosition(int source_position) {
|
||||
position_type_ = PositionType::kExpression;
|
||||
source_position_ = source_position;
|
||||
}
|
||||
|
||||
int source_position() const {
|
||||
DCHECK(is_valid());
|
||||
return source_position_;
|
||||
}
|
||||
|
||||
bool is_statement() const {
|
||||
return position_type_ == PositionType::kStatement;
|
||||
}
|
||||
bool is_expression() const {
|
||||
return position_type_ == PositionType::kExpression;
|
||||
}
|
||||
|
||||
bool is_valid() const { return position_type_ != PositionType::kNone; }
|
||||
void set_invalid() {
|
||||
position_type_ = PositionType::kNone;
|
||||
source_position_ = kUninitializedPosition;
|
||||
}
|
||||
|
||||
bool operator==(const BytecodeSourceInfo& other) const {
|
||||
return position_type_ == other.position_type_ &&
|
||||
source_position_ == other.source_position_;
|
||||
}
|
||||
|
||||
bool operator!=(const BytecodeSourceInfo& other) const {
|
||||
return position_type_ != other.position_type_ ||
|
||||
source_position_ != other.source_position_;
|
||||
}
|
||||
|
||||
private:
|
||||
enum class PositionType : uint8_t { kNone, kExpression, kStatement };
|
||||
|
||||
PositionType position_type_;
|
||||
int source_position_;
|
||||
};
|
||||
|
||||
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
|
||||
const BytecodeSourceInfo& info);
|
||||
|
||||
} // namespace interpreter
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_INTERPRETER_BYTECODE_SOURCE_INFO_H_
|
@ -1038,15 +1038,17 @@
|
||||
'interpreter/bytecode-generator.h',
|
||||
'interpreter/bytecode-label.cc',
|
||||
'interpreter/bytecode-label.h',
|
||||
'interpreter/bytecode-node.cc',
|
||||
'interpreter/bytecode-node.h',
|
||||
'interpreter/bytecode-operands.cc',
|
||||
'interpreter/bytecode-operands.h',
|
||||
'interpreter/bytecode-pipeline.cc',
|
||||
'interpreter/bytecode-pipeline.h',
|
||||
'interpreter/bytecode-register.cc',
|
||||
'interpreter/bytecode-register.h',
|
||||
'interpreter/bytecode-register-allocator.h',
|
||||
'interpreter/bytecode-register-optimizer.cc',
|
||||
'interpreter/bytecode-register-optimizer.h',
|
||||
'interpreter/bytecode-source-info.cc',
|
||||
'interpreter/bytecode-source-info.h',
|
||||
'interpreter/bytecode-traits.h',
|
||||
'interpreter/constant-array-builder.cc',
|
||||
'interpreter/constant-array-builder.h',
|
||||
|
@ -116,10 +116,11 @@ v8_executable("unittests") {
|
||||
"interpreter/bytecode-array-random-iterator-unittest.cc",
|
||||
"interpreter/bytecode-array-writer-unittest.cc",
|
||||
"interpreter/bytecode-decoder-unittest.cc",
|
||||
"interpreter/bytecode-node-unittest.cc",
|
||||
"interpreter/bytecode-operands-unittest.cc",
|
||||
"interpreter/bytecode-pipeline-unittest.cc",
|
||||
"interpreter/bytecode-register-allocator-unittest.cc",
|
||||
"interpreter/bytecode-register-optimizer-unittest.cc",
|
||||
"interpreter/bytecode-source-info-unittest.cc",
|
||||
"interpreter/bytecode-utils.h",
|
||||
"interpreter/bytecodes-unittest.cc",
|
||||
"interpreter/constant-array-builder-unittest.cc",
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include "src/factory.h"
|
||||
#include "src/interpreter/bytecode-array-writer.h"
|
||||
#include "src/interpreter/bytecode-label.h"
|
||||
#include "src/interpreter/bytecode-node.h"
|
||||
#include "src/interpreter/bytecode-register.h"
|
||||
#include "src/interpreter/bytecode-source-info.h"
|
||||
#include "src/interpreter/constant-array-builder.h"
|
||||
#include "src/isolate.h"
|
||||
#include "src/objects-inl.h"
|
||||
|
@ -4,9 +4,7 @@
|
||||
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "src/interpreter/bytecode-pipeline.h"
|
||||
#include "src/interpreter/bytecode-register-allocator.h"
|
||||
#include "src/isolate.h"
|
||||
#include "src/interpreter/bytecode-node.h"
|
||||
#include "test/unittests/test-utils.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -15,42 +13,6 @@ namespace interpreter {
|
||||
|
||||
using BytecodeNodeTest = TestWithIsolateAndZone;
|
||||
|
||||
TEST(BytecodeSourceInfo, Operations) {
|
||||
BytecodeSourceInfo x(0, true);
|
||||
CHECK_EQ(x.source_position(), 0);
|
||||
CHECK_EQ(x.is_statement(), true);
|
||||
CHECK_EQ(x.is_valid(), true);
|
||||
x.set_invalid();
|
||||
CHECK_EQ(x.is_statement(), false);
|
||||
CHECK_EQ(x.is_valid(), false);
|
||||
|
||||
x.MakeStatementPosition(1);
|
||||
BytecodeSourceInfo y(1, true);
|
||||
CHECK(x == y);
|
||||
CHECK(!(x != y));
|
||||
|
||||
x.set_invalid();
|
||||
CHECK(!(x == y));
|
||||
CHECK(x != y);
|
||||
|
||||
y.MakeStatementPosition(1);
|
||||
CHECK_EQ(y.source_position(), 1);
|
||||
CHECK_EQ(y.is_statement(), true);
|
||||
|
||||
y.MakeStatementPosition(2);
|
||||
CHECK_EQ(y.source_position(), 2);
|
||||
CHECK_EQ(y.is_statement(), true);
|
||||
|
||||
y.set_invalid();
|
||||
y.MakeExpressionPosition(3);
|
||||
CHECK_EQ(y.source_position(), 3);
|
||||
CHECK_EQ(y.is_statement(), false);
|
||||
|
||||
y.MakeStatementPosition(3);
|
||||
CHECK_EQ(y.source_position(), 3);
|
||||
CHECK_EQ(y.is_statement(), true);
|
||||
}
|
||||
|
||||
TEST_F(BytecodeNodeTest, Constructor1) {
|
||||
BytecodeNode node(Bytecode::kLdaZero);
|
||||
CHECK_EQ(node.bytecode(), Bytecode::kLdaZero);
|
@ -4,12 +4,8 @@
|
||||
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "src/factory.h"
|
||||
#include "src/interpreter/bytecode-label.h"
|
||||
#include "src/interpreter/bytecode-pipeline.h"
|
||||
#include "src/interpreter/bytecode-register-optimizer.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects.h"
|
||||
#include "test/unittests/test-utils.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -99,7 +95,6 @@ TEST_F(BytecodeRegisterOptimizerTest, TemporaryNotEmitted) {
|
||||
CHECK_EQ(write_count(), 0u);
|
||||
Register temp = NewTemporary();
|
||||
optimizer()->DoStar(temp);
|
||||
BytecodeNode node1(Bytecode::kStar, NewTemporary().ToOperand());
|
||||
ReleaseTemporaries(temp);
|
||||
CHECK_EQ(write_count(), 0u);
|
||||
optimizer()->PrepareForBytecode<Bytecode::kReturn, AccumulatorUse::kRead>();
|
||||
|
52
test/unittests/interpreter/bytecode-source-info-unittest.cc
Normal file
52
test/unittests/interpreter/bytecode-source-info-unittest.cc
Normal file
@ -0,0 +1,52 @@
|
||||
// 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.
|
||||
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "src/interpreter/bytecode-source-info.h"
|
||||
#include "test/unittests/test-utils.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace interpreter {
|
||||
|
||||
TEST(BytecodeSourceInfo, Operations) {
|
||||
BytecodeSourceInfo x(0, true);
|
||||
CHECK_EQ(x.source_position(), 0);
|
||||
CHECK_EQ(x.is_statement(), true);
|
||||
CHECK_EQ(x.is_valid(), true);
|
||||
x.set_invalid();
|
||||
CHECK_EQ(x.is_statement(), false);
|
||||
CHECK_EQ(x.is_valid(), false);
|
||||
|
||||
x.MakeStatementPosition(1);
|
||||
BytecodeSourceInfo y(1, true);
|
||||
CHECK(x == y);
|
||||
CHECK(!(x != y));
|
||||
|
||||
x.set_invalid();
|
||||
CHECK(!(x == y));
|
||||
CHECK(x != y);
|
||||
|
||||
y.MakeStatementPosition(1);
|
||||
CHECK_EQ(y.source_position(), 1);
|
||||
CHECK_EQ(y.is_statement(), true);
|
||||
|
||||
y.MakeStatementPosition(2);
|
||||
CHECK_EQ(y.source_position(), 2);
|
||||
CHECK_EQ(y.is_statement(), true);
|
||||
|
||||
y.set_invalid();
|
||||
y.MakeExpressionPosition(3);
|
||||
CHECK_EQ(y.source_position(), 3);
|
||||
CHECK_EQ(y.is_statement(), false);
|
||||
|
||||
y.MakeStatementPosition(3);
|
||||
CHECK_EQ(y.source_position(), 3);
|
||||
CHECK_EQ(y.is_statement(), true);
|
||||
}
|
||||
|
||||
} // namespace interpreter
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -104,10 +104,11 @@
|
||||
'interpreter/bytecode-array-random-iterator-unittest.cc',
|
||||
'interpreter/bytecode-array-writer-unittest.cc',
|
||||
'interpreter/bytecode-decoder-unittest.cc',
|
||||
'interpreter/bytecode-node-unittest.cc',
|
||||
'interpreter/bytecode-operands-unittest.cc',
|
||||
'interpreter/bytecode-pipeline-unittest.cc',
|
||||
'interpreter/bytecode-register-allocator-unittest.cc',
|
||||
'interpreter/bytecode-register-optimizer-unittest.cc',
|
||||
'interpreter/bytecode-source-info-unittest.cc',
|
||||
'interpreter/bytecode-utils.h',
|
||||
'interpreter/constant-array-builder-unittest.cc',
|
||||
'interpreter/interpreter-assembler-unittest.cc',
|
||||
|
Loading…
Reference in New Issue
Block a user