Commit c6414dac authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

Revert "[ignition] Merge bytecode array builder and writer"

This reverts commit 87f71769.

Reason for revert: Performance regressions https://chromeperf.appspot.com/group_report?rev=46185

Original change's description:
> [ignition] Merge bytecode array builder and writer
> 
> Move bytecode array writing logic into the array builder, allowing us to
> remove the bytecode array writer and bytecode node, and convert runtime
> operand writing to compile-time bytecode operand writing using the
> information statically known at compile time.
> 
> Bug: v8:6474
> Change-Id: I210cd9897fd41293745614e4a253c7c251dfffc9
> Reviewed-on: https://chromium-review.googlesource.com/533055
> Commit-Queue: Leszek Swirski <leszeks@chromium.org>
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#46183}

TBR=rmcilroy@chromium.org,leszeks@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: v8:6474
Bug: chromium:736646
Change-Id: I00287b2bbbb8efa5a3141bc9c2906f91a7d33e51
Reviewed-on: https://chromium-review.googlesource.com/549319Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46235}
parent bfad25a8
......@@ -1646,6 +1646,8 @@ v8_source_set("v8_base") {
"src/interpreter/bytecode-array-iterator.h",
"src/interpreter/bytecode-array-random-iterator.cc",
"src/interpreter/bytecode-array-random-iterator.h",
"src/interpreter/bytecode-array-writer.cc",
"src/interpreter/bytecode-array-writer.h",
"src/interpreter/bytecode-decoder.cc",
"src/interpreter/bytecode-decoder.h",
"src/interpreter/bytecode-flags.cc",
......@@ -1655,6 +1657,8 @@ v8_source_set("v8_base") {
"src/interpreter/bytecode-jump-table.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-register-allocator.h",
......
This diff is collapsed.
......@@ -5,10 +5,10 @@
#ifndef V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_
#define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_
#include <array>
#include "src/ast/ast.h"
#include "src/base/compiler-specific.h"
#include "src/globals.h"
#include "src/interpreter/bytecode-array-writer.h"
#include "src/interpreter/bytecode-flags.h"
#include "src/interpreter/bytecode-register-allocator.h"
#include "src/interpreter/bytecode-register.h"
......@@ -16,7 +16,6 @@
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/constant-array-builder.h"
#include "src/interpreter/handler-table-builder.h"
#include "src/source-position-table.h"
#include "src/zone/zone-containers.h"
namespace v8 {
......@@ -463,7 +462,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
latest_source_info_.MakeStatementPosition(expr->position());
}
bool RequiresImplicitReturn() const { return !exit_seen_in_block_; }
bool RequiresImplicitReturn() const { return !return_seen_in_block_; }
// Returns the raw operand value for the given register or register list.
uint32_t GetInputRegisterOperand(Register reg);
......@@ -487,103 +486,61 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
Zone* zone() const { return zone_; }
private:
// Maximum sized packed bytecode is comprised of a prefix bytecode,
// plus the actual bytecode, plus the maximum number of operands times
// the maximum operand size.
static const size_t kMaxSizeOfPackedBytecode =
2 * sizeof(Bytecode) +
Bytecodes::kMaxOperands * static_cast<size_t>(OperandSize::kLast);
// Constants that act as placeholders for jump operands to be
// patched. These have operand sizes that match the sizes of
// reserved constant pool entries.
static const uint32_t k8BitJumpPlaceholder = 0x7f;
static const uint32_t k16BitJumpPlaceholder =
k8BitJumpPlaceholder | (k8BitJumpPlaceholder << 8);
static const uint32_t k32BitJumpPlaceholder =
k16BitJumpPlaceholder | (k16BitJumpPlaceholder << 16);
void PatchJump(size_t jump_target, size_t jump_location);
void PatchJumpWith8BitOperand(size_t jump_location, int delta);
void PatchJumpWith16BitOperand(size_t jump_location, int delta);
void PatchJumpWith32BitOperand(size_t jump_location, int delta);
// Emit a non-jump bytecode with the given integer operand values.
template <AccumulatorUse accumulator_use, OperandType... operand_types>
void Write(Bytecode bytecode, BytecodeSourceInfo source_info,
std::array<uint32_t, sizeof...(operand_types)> operand_values);
// Emit a jump bytecode with the given integer operand values.
template <AccumulatorUse accumulator_use, OperandType... operand_types>
void WriteJump(Bytecode bytecode, BytecodeSourceInfo source_info,
BytecodeLabel* label,
std::array<uint32_t, sizeof...(operand_types)> operand_values);
// Emit a switch bytecode with the given integer operand values.
template <AccumulatorUse accumulator_use, OperandType... operand_types>
void WriteSwitch(
Bytecode bytecode, BytecodeSourceInfo source_info,
BytecodeJumpTable* jump_table,
std::array<uint32_t, sizeof...(operand_types)> operand_values);
// Emit the actual bytes of a bytecode and its operands. Called by Emit for
// jump and non-jump bytecodes.
template <OperandType... operand_types>
void EmitBytecode(
Bytecode bytecode,
std::array<uint32_t, sizeof...(operand_types)> operand_values);
#define DECLARE_BYTECODE_OUTPUT(Name, ...) \
template <typename... Operands> \
INLINE(void Output##Name(Operands... operands)); \
\
template <typename... Operands> \
INLINE(void Output##Name(BytecodeLabel* label, Operands... operands)); \
\
template <typename... Operands> \
INLINE( \
void Output##Name(BytecodeJumpTable* jump_table, Operands... operands));
friend class BytecodeRegisterAllocator;
template <Bytecode bytecode, AccumulatorUse accumulator_use,
OperandType... operand_types>
friend class BytecodeNodeBuilder;
const FeedbackVectorSpec* feedback_vector_spec() const {
return literal_->feedback_vector_spec();
}
// Returns the current source position for the given |bytecode|.
INLINE(BytecodeSourceInfo CurrentSourcePosition(Bytecode bytecode));
#define DECLARE_BYTECODE_OUTPUT(Name, ...) \
template <typename... Operands> \
INLINE(BytecodeNode Create##Name##Node(Operands... operands)); \
template <typename... Operands> \
INLINE(void Output##Name(Operands... operands)); \
template <typename... Operands> \
INLINE(void Output##Name(BytecodeLabel* label, Operands... operands));
BYTECODE_LIST(DECLARE_BYTECODE_OUTPUT)
#undef DECLARE_OPERAND_TYPE_INFO
INLINE(void OutputSwitchOnSmiNoFeedback(BytecodeJumpTable* jump_table));
void MaybeElideLastBytecode(Bytecode next_bytecode, bool has_source_info);
void InvalidateLastBytecode();
bool RegisterIsValid(Register reg) const;
bool RegisterListIsValid(RegisterList reg_list) const;
// Set position for return.
void SetReturnPosition();
// Returns the current source position for the given |bytecode|.
INLINE(BytecodeSourceInfo CurrentSourcePosition(Bytecode bytecode));
// Update the source table for the current offset with the given source info.
void AttachSourceInfo(const BytecodeSourceInfo& source_info);
// Sets a deferred source info which should be emitted before any future
// source info (either attached to a following bytecode or as a nop).
void SetDeferredSourceInfo(BytecodeSourceInfo source_info);
// Attach the deferred and given source infos to the current bytecode,
// possibly emitting a nop for the deferred info if both the deferred and
// given source infos are valid.
void AttachDeferredAndCurrentSourceInfo(BytecodeSourceInfo source_info);
// Either attach deferred source info to node, or emit it as a nop bytecode
// if node already have valid source info.
void AttachOrEmitDeferredSourceInfo(BytecodeNode* node);
// Write bytecode to bytecode array.
void Write(BytecodeNode* node);
void WriteJump(BytecodeNode* node, BytecodeLabel* label);
void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* label);
// Not implemented as the illegal bytecode is used inside internally
// to indicate a bytecode field is not valid or an error has occured
// during bytecode generation.
BytecodeArrayBuilder& Illegal();
template <Bytecode bytecode, AccumulatorUse accumulator_use,
OperandType... operand_types>
template <Bytecode bytecode, AccumulatorUse accumulator_use>
void PrepareToOutputBytecode();
void LeaveBasicBlock() { exit_seen_in_block_ = false; }
void LeaveBasicBlock() { return_seen_in_block_ = false; }
ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; }
const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; }
BytecodeArrayWriter* bytecode_array_writer() {
return &bytecode_array_writer_;
}
ConstantArrayBuilder* constant_array_builder() {
return &constant_array_builder_;
}
......@@ -593,45 +550,24 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
HandlerTableBuilder* handler_table_builder() {
return &handler_table_builder_;
}
SourcePositionTableBuilder* source_position_table_builder() {
return &source_position_table_builder_;
}
const FeedbackVectorSpec* feedback_vector_spec() const {
return literal_->feedback_vector_spec();
}
void set_latest_source_info(BytecodeSourceInfo source_info) {
latest_source_info_ = source_info;
}
Zone* zone_;
ZoneVector<uint8_t> bytecodes_;
FunctionLiteral* literal_;
bool bytecode_generated_;
ConstantArrayBuilder constant_array_builder_;
HandlerTableBuilder handler_table_builder_;
SourcePositionTableBuilder source_position_table_builder_;
bool return_seen_in_block_;
int parameter_count_;
int local_register_count_;
int return_position_;
BytecodeRegisterAllocator register_allocator_;
BytecodeArrayWriter bytecode_array_writer_;
BytecodeRegisterOptimizer* register_optimizer_;
BytecodeSourceInfo latest_source_info_;
BytecodeSourceInfo deferred_source_info_;
int parameter_count_;
int local_register_count_;
int return_position_;
int unbound_jumps_;
bool bytecode_generated_;
bool elide_noneffectful_bytecodes_;
bool exit_seen_in_block_;
bool last_bytecode_had_source_info_;
size_t last_bytecode_offset_;
Bytecode last_bytecode_;
static int const kNoFeedbackSlot = 0;
friend class BytecodeArrayBuilderTest;
DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder);
};
......
This diff is collapsed.
// Copyright 2015 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_ARRAY_WRITER_H_
#define V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_
#include "src/base/compiler-specific.h"
#include "src/globals.h"
#include "src/interpreter/bytecodes.h"
#include "src/source-position-table.h"
namespace v8 {
namespace internal {
class SourcePositionTableBuilder;
namespace interpreter {
class BytecodeLabel;
class BytecodeNode;
class BytecodeJumpTable;
class ConstantArrayBuilder;
// Class for emitting bytecode as the final stage of the bytecode
// generation pipeline.
class V8_EXPORT_PRIVATE BytecodeArrayWriter final {
public:
BytecodeArrayWriter(
Zone* zone, ConstantArrayBuilder* constant_array_builder,
SourcePositionTableBuilder::RecordingMode source_position_mode);
void Write(BytecodeNode* node);
void WriteJump(BytecodeNode* node, BytecodeLabel* label);
void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table);
void BindLabel(BytecodeLabel* label);
void BindLabel(const BytecodeLabel& target, BytecodeLabel* label);
void BindJumpTableEntry(BytecodeJumpTable* jump_table, int case_value);
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,
// plus the actual bytecode, plus the maximum number of operands times
// the maximum operand size.
static const size_t kMaxSizeOfPackedBytecode =
2 * sizeof(Bytecode) +
Bytecodes::kMaxOperands * static_cast<size_t>(OperandSize::kLast);
// Constants that act as placeholders for jump operands to be
// patched. These have operand sizes that match the sizes of
// reserved constant pool entries.
const uint32_t k8BitJumpPlaceholder = 0x7f;
const uint32_t k16BitJumpPlaceholder =
k8BitJumpPlaceholder | (k8BitJumpPlaceholder << 8);
const uint32_t k32BitJumpPlaceholder =
k16BitJumpPlaceholder | (k16BitJumpPlaceholder << 16);
void PatchJump(size_t jump_target, size_t jump_location);
void PatchJumpWith8BitOperand(size_t jump_location, int delta);
void PatchJumpWith16BitOperand(size_t jump_location, int delta);
void PatchJumpWith32BitOperand(size_t jump_location, int delta);
void EmitBytecode(const BytecodeNode* const node);
void EmitJump(BytecodeNode* node, BytecodeLabel* label);
void EmitSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table);
void UpdateSourcePositionTable(const BytecodeNode* const node);
void UpdateExitSeenInBlock(Bytecode bytecode);
void MaybeElideLastBytecode(Bytecode next_bytecode, bool has_source_info);
void InvalidateLastBytecode();
ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; }
SourcePositionTableBuilder* source_position_table_builder() {
return &source_position_table_builder_;
}
ConstantArrayBuilder* constant_array_builder() {
return constant_array_builder_;
}
ZoneVector<uint8_t> bytecodes_;
int unbound_jumps_;
SourcePositionTableBuilder source_position_table_builder_;
ConstantArrayBuilder* constant_array_builder_;
Bytecode last_bytecode_;
size_t last_bytecode_offset_;
bool last_bytecode_had_source_info_;
bool elide_noneffectful_bytecodes_;
bool exit_seen_in_block_;
friend class BytecodeArrayWriterUnittest;
DISALLOW_COPY_AND_ASSIGN(BytecodeArrayWriter);
};
} // namespace interpreter
} // namespace internal
} // namespace v8
#endif // V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_
......@@ -78,7 +78,7 @@ class V8_EXPORT_PRIVATE BytecodeJumpTable final : public ZoneObject {
int size_;
int case_value_base_;
friend class BytecodeArrayBuilder;
friend class BytecodeArrayWriter;
};
} // namespace interpreter
......
......@@ -50,7 +50,7 @@ class V8_EXPORT_PRIVATE BytecodeLabel final {
bool bound_;
size_t offset_;
friend class BytecodeArrayBuilder;
friend class BytecodeArrayWriter;
};
// Class representing a branch target of multiple jumps.
......
// 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-node.h"
#include <iomanip>
#include "src/source-position-table.h"
namespace v8 {
namespace internal {
namespace interpreter {
void BytecodeNode::Print(std::ostream& os) const {
#ifdef DEBUG
std::ios saved_state(nullptr);
saved_state.copyfmt(os);
os << Bytecodes::ToString(bytecode_);
for (int i = 0; i < operand_count(); ++i) {
os << ' ' << std::setw(8) << std::setfill('0') << std::hex << operands_[i];
}
os.copyfmt(saved_state);
if (source_info_.is_valid()) {
os << ' ' << source_info_;
}
os << '\n';
#else
os << static_cast<const void*>(this);
#endif // DEBUG
}
bool BytecodeNode::operator==(const BytecodeNode& other) const {
if (this == &other) {
return true;
} else if (this->bytecode() != other.bytecode() ||
this->source_info() != other.source_info()) {
return false;
} else {
for (int i = 0; i < this->operand_count(); ++i) {
if (this->operand(i) != other.operand(i)) {
return false;
}
}
}
return true;
}
std::ostream& operator<<(std::ostream& os, const BytecodeNode& node) {
node.Print(os);
return os;
}
} // namespace interpreter
} // namespace internal
} // namespace v8
This diff is collapsed.
......@@ -624,37 +624,6 @@ class V8_EXPORT_PRIVATE Bytecodes final {
return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
}
// Return the constant operand version of the given immediate operand forward
// jump.
static Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) {
DCHECK(IsJumpImmediate(jump_bytecode));
DCHECK(IsForwardJump(jump_bytecode));
switch (jump_bytecode) {
case Bytecode::kJump:
return Bytecode::kJumpConstant;
case Bytecode::kJumpIfTrue:
return Bytecode::kJumpIfTrueConstant;
case Bytecode::kJumpIfFalse:
return Bytecode::kJumpIfFalseConstant;
case Bytecode::kJumpIfToBooleanTrue:
return Bytecode::kJumpIfToBooleanTrueConstant;
case Bytecode::kJumpIfToBooleanFalse:
return Bytecode::kJumpIfToBooleanFalseConstant;
case Bytecode::kJumpIfNull:
return Bytecode::kJumpIfNullConstant;
case Bytecode::kJumpIfNotNull:
return Bytecode::kJumpIfNotNullConstant;
case Bytecode::kJumpIfUndefined:
return Bytecode::kJumpIfUndefinedConstant;
case Bytecode::kJumpIfNotUndefined:
return Bytecode::kJumpIfNotUndefinedConstant;
case Bytecode::kJumpIfJSReceiver:
return Bytecode::kJumpIfJSReceiverConstant;
default:
UNREACHABLE();
}
}
// Returns true if the bytecode is a switch.
static constexpr bool IsSwitch(Bytecode bytecode) {
return bytecode == Bytecode::kSwitchOnSmiNoFeedback;
......@@ -669,13 +638,6 @@ class V8_EXPORT_PRIVATE Bytecodes final {
IsJumpWithoutEffects(bytecode) || IsSwitch(bytecode));
}
// True if the given bytecode unconditionally ends the current basic block.
static constexpr bool EndsBasicBlock(Bytecode bytecode) {
return bytecode == Bytecode::kReturn || bytecode == Bytecode::kThrow ||
bytecode == Bytecode::kReThrow || bytecode == Bytecode::kJump ||
bytecode == Bytecode::kJumpConstant;
}
// Returns true if the bytecode is Ldar or Star.
static constexpr bool IsLdarOrStar(Bytecode bytecode) {
return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
......
......@@ -1081,6 +1081,8 @@
'interpreter/bytecode-array-iterator.h',
'interpreter/bytecode-array-random-iterator.cc',
'interpreter/bytecode-array-random-iterator.h',
'interpreter/bytecode-array-writer.cc',
'interpreter/bytecode-array-writer.h',
'interpreter/bytecode-decoder.cc',
'interpreter/bytecode-decoder.h',
'interpreter/bytecode-flags.cc',
......@@ -1089,6 +1091,8 @@
'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-register.cc',
......
......@@ -75,12 +75,12 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 13
bytecode array length: 14
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 44 S> */ B(LdaSmi), I8(10),
B(Star), R(0),
/* 48 S> */ B(Nop),
/* 48 S> */ B(LdaSmi), I8(20),
/* 50 E> */ B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), U8(0),
B(LdaUndefined),
/* 56 S> */ B(Return),
......
......@@ -94,7 +94,7 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 26
bytecode array length: 27
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
......@@ -105,7 +105,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 44 S> */ B(LdaSmi), I8(10),
/* 44 E> */ B(StaCurrentContextSlot), U8(4),
/* 48 S> */ B(Nop),
/* 48 S> */ B(LdaSmi), I8(20),
/* 50 E> */ B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), U8(0),
B(LdaUndefined),
/* 82 S> */ B(Return),
......
......@@ -62,7 +62,7 @@ bytecodes: [
B(Star), R(0),
B(Star), R(1),
/* 74 S> */ B(Jump), U8(2),
/* 84 S> */ B(LdaUndefined),
B(LdaUndefined),
/* 94 S> */ B(Return),
]
constant pool: [
......
......@@ -116,7 +116,9 @@ v8_executable("unittests") {
"interpreter/bytecode-array-builder-unittest.cc",
"interpreter/bytecode-array-iterator-unittest.cc",
"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-register-allocator-unittest.cc",
"interpreter/bytecode-register-optimizer-unittest.cc",
......
This diff is collapsed.
// 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-node.h"
#include "test/unittests/test-utils.h"
namespace v8 {
namespace internal {
namespace interpreter {
using BytecodeNodeTest = TestWithIsolateAndZone;
TEST_F(BytecodeNodeTest, Constructor1) {
BytecodeNode node(Bytecode::kLdaZero);
CHECK_EQ(node.bytecode(), Bytecode::kLdaZero);
CHECK_EQ(node.operand_count(), 0);
CHECK(!node.source_info().is_valid());
}
TEST_F(BytecodeNodeTest, Constructor2) {
uint32_t operands[] = {0x11};
BytecodeNode node(Bytecode::kJumpIfTrue, operands[0]);
CHECK_EQ(node.bytecode(), Bytecode::kJumpIfTrue);
CHECK_EQ(node.operand_count(), 1);
CHECK_EQ(node.operand(0), operands[0]);
CHECK(!node.source_info().is_valid());
}
TEST_F(BytecodeNodeTest, Constructor3) {
uint32_t operands[] = {0x11, 0x22};
BytecodeNode node(Bytecode::kLdaGlobal, operands[0], operands[1]);
CHECK_EQ(node.bytecode(), Bytecode::kLdaGlobal);
CHECK_EQ(node.operand_count(), 2);
CHECK_EQ(node.operand(0), operands[0]);
CHECK_EQ(node.operand(1), operands[1]);
CHECK(!node.source_info().is_valid());
}
TEST_F(BytecodeNodeTest, Constructor4) {
uint32_t operands[] = {0x11, 0x22, 0x33};
BytecodeNode node(Bytecode::kLdaNamedProperty, operands[0], operands[1],
operands[2]);
CHECK_EQ(node.operand_count(), 3);
CHECK_EQ(node.bytecode(), Bytecode::kLdaNamedProperty);
CHECK_EQ(node.operand(0), operands[0]);
CHECK_EQ(node.operand(1), operands[1]);
CHECK_EQ(node.operand(2), operands[2]);
CHECK(!node.source_info().is_valid());
}
TEST_F(BytecodeNodeTest, Constructor5) {
uint32_t operands[] = {0x71, 0xa5, 0x5a, 0xfc};
BytecodeNode node(Bytecode::kForInNext, operands[0], operands[1], operands[2],
operands[3]);
CHECK_EQ(node.operand_count(), 4);
CHECK_EQ(node.bytecode(), Bytecode::kForInNext);
CHECK_EQ(node.operand(0), operands[0]);
CHECK_EQ(node.operand(1), operands[1]);
CHECK_EQ(node.operand(2), operands[2]);
CHECK_EQ(node.operand(3), operands[3]);
CHECK(!node.source_info().is_valid());
}
TEST_F(BytecodeNodeTest, Equality) {
uint32_t operands[] = {0x71, 0xa5, 0x5a, 0xfc};
BytecodeNode node(Bytecode::kForInNext, operands[0], operands[1], operands[2],
operands[3]);
CHECK_EQ(node, node);
BytecodeNode other(Bytecode::kForInNext, operands[0], operands[1],
operands[2], operands[3]);
CHECK_EQ(node, other);
}
TEST_F(BytecodeNodeTest, EqualityWithSourceInfo) {
uint32_t operands[] = {0x71, 0xa5, 0x5a, 0xfc};
BytecodeSourceInfo first_source_info(3, true);
BytecodeNode node(Bytecode::kForInNext, operands[0], operands[1], operands[2],
operands[3], first_source_info);
CHECK_EQ(node, node);
BytecodeSourceInfo second_source_info(3, true);
BytecodeNode other(Bytecode::kForInNext, operands[0], operands[1],
operands[2], operands[3], second_source_info);
CHECK_EQ(node, other);
}
TEST_F(BytecodeNodeTest, NoEqualityWithDifferentSourceInfo) {
uint32_t operands[] = {0x71, 0xa5, 0x5a, 0xfc};
BytecodeSourceInfo source_info(77, true);
BytecodeNode node(Bytecode::kForInNext, operands[0], operands[1], operands[2],
operands[3], source_info);
BytecodeNode other(Bytecode::kForInNext, operands[0], operands[1],
operands[2], operands[3]);
CHECK_NE(node, other);
}
} // namespace interpreter
} // namespace internal
} // namespace v8
......@@ -114,7 +114,9 @@
'interpreter/bytecode-array-builder-unittest.cc',
'interpreter/bytecode-array-iterator-unittest.cc',
'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-register-allocator-unittest.cc',
'interpreter/bytecode-register-optimizer-unittest.cc',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment