Commit 40511877 authored by oth's avatar oth Committed by Commit bot

[interpreter] Introduce binary op bytecodes for Smi operand.

Introduces fused bytecodes for fusing LdaSmi followed by a binary op bytecode.
The chosen bytecodes are used frequently in Octane: AddSmi, SubSmi,
BitwiseOrSmi, BitwiseAndSmi, ShiftLeftSmi, ShiftRightSmi.

There are additional code stubs for these operations that are biased towards
both the left hand and right hand operands being Smis.

BUG=v8:4280
LOG=N

Review-Url: https://codereview.chromium.org/2111923002
Cr-Commit-Position: refs/heads/master@{#37531}
parent ddc75cc1
...@@ -1698,7 +1698,7 @@ compiler::Node* IncStub::Generate(CodeStubAssembler* assembler, ...@@ -1698,7 +1698,7 @@ compiler::Node* IncStub::Generate(CodeStubAssembler* assembler,
Node* pair = assembler->SmiAddWithOverflow(value, one); Node* pair = assembler->SmiAddWithOverflow(value, one);
Node* overflow = assembler->Projection(1, pair); Node* overflow = assembler->Projection(1, pair);
// Check if the Smi additon overflowed. // Check if the Smi addition overflowed.
Label if_overflow(assembler), if_notoverflow(assembler); Label if_overflow(assembler), if_notoverflow(assembler);
assembler->Branch(overflow, &if_overflow, &if_notoverflow); assembler->Branch(overflow, &if_overflow, &if_notoverflow);
......
...@@ -1155,6 +1155,45 @@ void BytecodeGraphBuilder::VisitShiftRightLogical() { ...@@ -1155,6 +1155,45 @@ void BytecodeGraphBuilder::VisitShiftRightLogical() {
BuildBinaryOp(javascript()->ShiftRightLogical(hints)); BuildBinaryOp(javascript()->ShiftRightLogical(hints));
} }
void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* js_op) {
FrameStateBeforeAndAfter states(this);
Node* left =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
Node* node = NewNode(js_op, left, right);
environment()->BindAccumulator(node, &states);
}
void BytecodeGraphBuilder::VisitAddSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any();
BuildBinaryOpWithImmediate(javascript()->Add(hints));
}
void BytecodeGraphBuilder::VisitSubSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any();
BuildBinaryOpWithImmediate(javascript()->Subtract(hints));
}
void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any();
BuildBinaryOpWithImmediate(javascript()->BitwiseOr(hints));
}
void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any();
BuildBinaryOpWithImmediate(javascript()->BitwiseAnd(hints));
}
void BytecodeGraphBuilder::VisitShiftLeftSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any();
BuildBinaryOpWithImmediate(javascript()->ShiftLeft(hints));
}
void BytecodeGraphBuilder::VisitShiftRightSmi() {
BinaryOperationHints hints = BinaryOperationHints::Any();
BuildBinaryOpWithImmediate(javascript()->ShiftRight(hints));
}
void BytecodeGraphBuilder::VisitInc() { void BytecodeGraphBuilder::VisitInc() {
FrameStateBeforeAndAfter states(this); FrameStateBeforeAndAfter states(this);
// Note: Use subtract -1 here instead of add 1 to ensure we always convert to // Note: Use subtract -1 here instead of add 1 to ensure we always convert to
......
...@@ -124,6 +124,7 @@ class BytecodeGraphBuilder { ...@@ -124,6 +124,7 @@ class BytecodeGraphBuilder {
void BuildCall(TailCallMode tail_call_mode); void BuildCall(TailCallMode tail_call_mode);
void BuildThrow(); void BuildThrow();
void BuildBinaryOp(const Operator* op); void BuildBinaryOp(const Operator* op);
void BuildBinaryOpWithImmediate(const Operator* op);
void BuildCompareOp(const Operator* op); void BuildCompareOp(const Operator* op);
void BuildDelete(LanguageMode language_mode); void BuildDelete(LanguageMode language_mode);
void BuildCastOperator(const Operator* op); void BuildCastOperator(const Operator* op);
......
...@@ -125,7 +125,8 @@ bool BytecodePeepholeOptimizer::CanElideCurrent( ...@@ -125,7 +125,8 @@ bool BytecodePeepholeOptimizer::CanElideCurrent(
return true; return true;
} else { } else {
// Additional candidates for eliding current: // Additional candidates for eliding current:
// (i) ToNumber if the last puts a number in the accumulator. // (i) current is Nop.
// (ii) ToNumber if the last puts a number in the accumulator.
return false; return false;
} }
} }
...@@ -188,6 +189,18 @@ void TransformLdaStarToLdrLdar(Bytecode new_bytecode, BytecodeNode* const last, ...@@ -188,6 +189,18 @@ void TransformLdaStarToLdrLdar(Bytecode new_bytecode, BytecodeNode* const last,
current->set_bytecode(Bytecode::kLdar, current->operand(0)); current->set_bytecode(Bytecode::kLdar, current->operand(0));
} }
void TransformToBinaryOpWithSmiOnRhs(Bytecode new_bytecode,
BytecodeNode* const last,
BytecodeNode* const current) {
DCHECK(Bytecodes::IsLdaSmiOrLdaZero(last->bytecode()));
uint32_t imm_operand =
last->bytecode() == Bytecode::kLdaSmi ? last->operand(0) : 0;
current->set_bytecode(new_bytecode, imm_operand, current->operand(0));
if (last->source_info().is_valid()) {
current->source_info().Clone(last->source_info());
}
}
} // namespace } // namespace
bool BytecodePeepholeOptimizer::TransformLastAndCurrentBytecodes( bool BytecodePeepholeOptimizer::TransformLastAndCurrentBytecodes(
...@@ -216,7 +229,43 @@ bool BytecodePeepholeOptimizer::TransformLastAndCurrentBytecodes( ...@@ -216,7 +229,43 @@ bool BytecodePeepholeOptimizer::TransformLastAndCurrentBytecodes(
default: default:
break; break;
} }
} else if (Bytecodes::IsLdaSmiOrLdaZero(last_.bytecode()) &&
(!last_.source_info().is_valid() ||
!current->source_info().is_valid())) {
switch (current->bytecode()) {
case Bytecode::kAdd:
TransformToBinaryOpWithSmiOnRhs(Bytecode::kAddSmi, &last_, current);
InvalidateLast();
return true;
case Bytecode::kSub:
TransformToBinaryOpWithSmiOnRhs(Bytecode::kSubSmi, &last_, current);
InvalidateLast();
return true;
case Bytecode::kBitwiseOr:
TransformToBinaryOpWithSmiOnRhs(Bytecode::kBitwiseOrSmi, &last_,
current);
InvalidateLast();
return true;
case Bytecode::kBitwiseAnd:
TransformToBinaryOpWithSmiOnRhs(Bytecode::kBitwiseAndSmi, &last_,
current);
InvalidateLast();
return true;
case Bytecode::kShiftLeft:
TransformToBinaryOpWithSmiOnRhs(Bytecode::kShiftLeftSmi, &last_,
current);
InvalidateLast();
return true;
case Bytecode::kShiftRight:
TransformToBinaryOpWithSmiOnRhs(Bytecode::kShiftRightSmi, &last_,
current);
InvalidateLast();
return true;
default:
break;
}
} }
return false; return false;
} }
...@@ -279,7 +328,6 @@ bool BytecodePeepholeOptimizer::CanElideLast( ...@@ -279,7 +328,6 @@ bool BytecodePeepholeOptimizer::CanElideLast(
BytecodeNode* BytecodePeepholeOptimizer::Optimize(BytecodeNode* current) { BytecodeNode* BytecodePeepholeOptimizer::Optimize(BytecodeNode* current) {
TryToRemoveLastExpressionPosition(current); TryToRemoveLastExpressionPosition(current);
if (TransformCurrentBytecode(current) || if (TransformCurrentBytecode(current) ||
TransformLastAndCurrentBytecodes(current)) { TransformLastAndCurrentBytecodes(current)) {
return current; return current;
......
...@@ -59,17 +59,6 @@ BytecodeNode& BytecodeNode::operator=(const BytecodeNode& other) { ...@@ -59,17 +59,6 @@ BytecodeNode& BytecodeNode::operator=(const BytecodeNode& other) {
return *this; return *this;
} }
void BytecodeNode::set_bytecode(Bytecode bytecode) {
DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
bytecode_ = bytecode;
}
void BytecodeNode::set_bytecode(Bytecode bytecode, uint32_t operand0) {
DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1);
bytecode_ = bytecode;
operands_[0] = operand0;
}
void BytecodeNode::Clone(const BytecodeNode* const other) { void BytecodeNode::Clone(const BytecodeNode* const other) {
memcpy(this, other, sizeof(*other)); memcpy(this, other, sizeof(*other));
} }
......
...@@ -151,8 +151,21 @@ class BytecodeNode final : ZoneObject { ...@@ -151,8 +151,21 @@ class BytecodeNode final : ZoneObject {
BytecodeNode(const BytecodeNode& other); BytecodeNode(const BytecodeNode& other);
BytecodeNode& operator=(const BytecodeNode& other); BytecodeNode& operator=(const BytecodeNode& other);
void set_bytecode(Bytecode bytecode); void set_bytecode(Bytecode bytecode) {
void set_bytecode(Bytecode bytecode, uint32_t operand0); DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
bytecode_ = bytecode;
}
void set_bytecode(Bytecode bytecode, uint32_t operand0) {
DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1);
bytecode_ = bytecode;
operands_[0] = operand0;
}
void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1) {
DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2);
bytecode_ = bytecode;
operands_[0] = operand0;
operands_[1] = operand1;
}
// Clone |other|. // Clone |other|.
void Clone(const BytecodeNode* const other); void Clone(const BytecodeNode* const other);
......
...@@ -473,6 +473,11 @@ bool Bytecodes::IsLdarOrStar(Bytecode bytecode) { ...@@ -473,6 +473,11 @@ bool Bytecodes::IsLdarOrStar(Bytecode bytecode) {
return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar; return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
} }
// static
bool Bytecodes::IsLdaSmiOrLdaZero(Bytecode bytecode) {
return bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaZero;
}
// static // static
bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) { bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
switch (bytecode) { switch (bytecode) {
......
...@@ -157,6 +157,18 @@ namespace interpreter { ...@@ -157,6 +157,18 @@ namespace interpreter {
V(ShiftRight, AccumulatorUse::kReadWrite, OperandType::kReg) \ V(ShiftRight, AccumulatorUse::kReadWrite, OperandType::kReg) \
V(ShiftRightLogical, AccumulatorUse::kReadWrite, OperandType::kReg) \ V(ShiftRightLogical, AccumulatorUse::kReadWrite, OperandType::kReg) \
\ \
/* Binary operators with immediate operands */ \
V(AddSmi, AccumulatorUse::kWrite, OperandType::kImm, OperandType::kReg) \
V(SubSmi, AccumulatorUse::kWrite, OperandType::kImm, OperandType::kReg) \
V(BitwiseOrSmi, AccumulatorUse::kWrite, OperandType::kImm, \
OperandType::kReg) \
V(BitwiseAndSmi, AccumulatorUse::kWrite, OperandType::kImm, \
OperandType::kReg) \
V(ShiftLeftSmi, AccumulatorUse::kWrite, OperandType::kImm, \
OperandType::kReg) \
V(ShiftRightSmi, AccumulatorUse::kWrite, OperandType::kImm, \
OperandType::kReg) \
\
/* Unary Operators */ \ /* Unary Operators */ \
V(Inc, AccumulatorUse::kReadWrite) \ V(Inc, AccumulatorUse::kReadWrite) \
V(Dec, AccumulatorUse::kReadWrite) \ V(Dec, AccumulatorUse::kReadWrite) \
...@@ -592,6 +604,9 @@ class Bytecodes { ...@@ -592,6 +604,9 @@ class Bytecodes {
// Returns true if the bytecode is Ldar or Star. // Returns true if the bytecode is Ldar or Star.
static bool IsLdarOrStar(Bytecode bytecode); static bool IsLdarOrStar(Bytecode bytecode);
// Returns true if the bytecode is LdaSmi or LdaZero.
static bool IsLdaSmiOrLdaZero(Bytecode bytecode);
// Returns true if the bytecode has wider operand forms. // Returns true if the bytecode has wider operand forms.
static bool IsBytecodeWithScalableOperands(Bytecode bytecode); static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
......
...@@ -836,6 +836,174 @@ void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) { ...@@ -836,6 +836,174 @@ void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) {
DoBinaryOp<ShiftRightLogicalStub>(assembler); DoBinaryOp<ShiftRightLogicalStub>(assembler);
} }
// AddSmi <imm> <reg>
//
// Adds an immediate value <imm> to register <reg>. For this
// operation <reg> is the lhs operand and <imm> is the <rhs> operand.
void Interpreter::DoAddSmi(InterpreterAssembler* assembler) {
Variable var_result(assembler, MachineRepresentation::kTagged);
Label fastpath(assembler), slowpath(assembler, Label::kDeferred),
end(assembler);
Node* reg_index = __ BytecodeOperandReg(1);
Node* left = __ LoadRegister(reg_index);
Node* raw_int = __ BytecodeOperandImm(0);
Node* right = __ SmiTag(raw_int);
// {right} is known to be a Smi.
// Check if the {left} is a Smi take the fast path.
__ BranchIf(__ WordIsSmi(left), &fastpath, &slowpath);
__ Bind(&fastpath);
{
// Try fast Smi addition first.
Node* pair = __ SmiAddWithOverflow(left, right);
Node* overflow = __ Projection(1, pair);
// Check if the Smi additon overflowed.
Label if_notoverflow(assembler);
__ BranchIf(overflow, &slowpath, &if_notoverflow);
__ Bind(&if_notoverflow);
{
var_result.Bind(__ Projection(0, pair));
__ Goto(&end);
}
}
__ Bind(&slowpath);
{
Node* context = __ GetContext();
Callable callable = CodeFactory::Add(__ isolate());
var_result.Bind(__ CallStub(callable, context, left, right));
__ Goto(&end);
}
__ Bind(&end);
{
__ SetAccumulator(var_result.value());
__ Dispatch();
}
}
// SubSmi <imm> <reg>
//
// Subtracts an immediate value <imm> to register <reg>. For this
// operation <reg> is the lhs operand and <imm> is the rhs operand.
void Interpreter::DoSubSmi(InterpreterAssembler* assembler) {
Variable var_result(assembler, MachineRepresentation::kTagged);
Label fastpath(assembler), slowpath(assembler, Label::kDeferred),
end(assembler);
Node* reg_index = __ BytecodeOperandReg(1);
Node* left = __ LoadRegister(reg_index);
Node* raw_int = __ BytecodeOperandImm(0);
Node* right = __ SmiTag(raw_int);
// {right} is known to be a Smi.
// Check if the {left} is a Smi take the fast path.
__ BranchIf(__ WordIsSmi(left), &fastpath, &slowpath);
__ Bind(&fastpath);
{
// Try fast Smi subtraction first.
Node* pair = __ SmiSubWithOverflow(left, right);
Node* overflow = __ Projection(1, pair);
// Check if the Smi subtraction overflowed.
Label if_notoverflow(assembler);
__ BranchIf(overflow, &slowpath, &if_notoverflow);
__ Bind(&if_notoverflow);
{
var_result.Bind(__ Projection(0, pair));
__ Goto(&end);
}
}
__ Bind(&slowpath);
{
Node* context = __ GetContext();
Callable callable = CodeFactory::Subtract(__ isolate());
var_result.Bind(__ CallStub(callable, context, left, right));
__ Goto(&end);
}
__ Bind(&end);
{
__ SetAccumulator(var_result.value());
__ Dispatch();
}
}
// BitwiseOr <imm> <reg>
//
// BitwiseOr <reg> with <imm>. For this operation <reg> is the lhs
// operand and <imm> is the rhs operand.
void Interpreter::DoBitwiseOrSmi(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(1);
Node* left = __ LoadRegister(reg_index);
Node* raw_int = __ BytecodeOperandImm(0);
Node* right = __ SmiTag(raw_int);
Node* context = __ GetContext();
Node* lhs_value = __ TruncateTaggedToWord32(context, left);
Node* rhs_value = __ SmiToWord32(right);
Node* value = __ Word32Or(lhs_value, rhs_value);
Node* result = __ ChangeInt32ToTagged(value);
__ SetAccumulator(result);
__ Dispatch();
}
// BitwiseAnd <imm> <reg>
//
// BitwiseAnd <reg> with <imm>. For this operation <reg> is the lhs
// operand and <imm> is the rhs operand.
void Interpreter::DoBitwiseAndSmi(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(1);
Node* left = __ LoadRegister(reg_index);
Node* raw_int = __ BytecodeOperandImm(0);
Node* right = __ SmiTag(raw_int);
Node* context = __ GetContext();
Node* lhs_value = __ TruncateTaggedToWord32(context, left);
Node* rhs_value = __ SmiToWord32(right);
Node* value = __ Word32And(lhs_value, rhs_value);
Node* result = __ ChangeInt32ToTagged(value);
__ SetAccumulator(result);
__ Dispatch();
}
// ShiftLeftSmi <imm> <reg>
//
// Left shifts register <src> by the count specified in <imm>.
// Register <src> is converted to an int32 before the operation. The 5
// lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F).
void Interpreter::DoShiftLeftSmi(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(1);
Node* left = __ LoadRegister(reg_index);
Node* raw_int = __ BytecodeOperandImm(0);
Node* right = __ SmiTag(raw_int);
Node* context = __ GetContext();
Node* lhs_value = __ TruncateTaggedToWord32(context, left);
Node* rhs_value = __ SmiToWord32(right);
Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f));
Node* value = __ Word32Shl(lhs_value, shift_count);
Node* result = __ ChangeInt32ToTagged(value);
__ SetAccumulator(result);
__ Dispatch();
}
// ShiftRightSmi <imm> <reg>
//
// Right shifts register <src> by the count specified in <imm>.
// Register <src> is converted to an int32 before the operation. The 5
// lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F).
void Interpreter::DoShiftRightSmi(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(1);
Node* left = __ LoadRegister(reg_index);
Node* raw_int = __ BytecodeOperandImm(0);
Node* right = __ SmiTag(raw_int);
Node* context = __ GetContext();
Node* lhs_value = __ TruncateTaggedToWord32(context, left);
Node* rhs_value = __ SmiToWord32(right);
Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f));
Node* value = __ Word32Sar(lhs_value, shift_count);
Node* result = __ ChangeInt32ToTagged(value);
__ SetAccumulator(result);
__ Dispatch();
}
void Interpreter::DoUnaryOp(Callable callable, void Interpreter::DoUnaryOp(Callable callable,
InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Node* target = __ HeapConstant(callable.code()); Node* target = __ HeapConstant(callable.code());
......
...@@ -74,6 +74,11 @@ class Interpreter { ...@@ -74,6 +74,11 @@ class Interpreter {
template <class Generator> template <class Generator>
void DoBinaryOp(InterpreterAssembler* assembler); void DoBinaryOp(InterpreterAssembler* assembler);
// Generates code to perform the binary operation via |Generator| using
// an immediate value rather the accumulator as the rhs operand.
template <class Generator>
void DoBinaryOpWithImmediate(InterpreterAssembler* assembler);
// Generates code to perform the unary operation via |callable|. // Generates code to perform the unary operation via |callable|.
void DoUnaryOp(Callable callable, InterpreterAssembler* assembler); void DoUnaryOp(Callable callable, InterpreterAssembler* assembler);
......
...@@ -31,7 +31,7 @@ snippet: " ...@@ -31,7 +31,7 @@ snippet: "
" "
frame size: 3 frame size: 3
parameter count: 1 parameter count: 1
bytecode array length: 35 bytecode array length: 34
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1), /* 42 S> */ B(LdaSmi), U8(1),
...@@ -44,8 +44,7 @@ bytecodes: [ ...@@ -44,8 +44,7 @@ bytecodes: [
/* 54 E> */ B(StaKeyedPropertySloppy), R(2), R(1), U8(1), /* 54 E> */ B(StaKeyedPropertySloppy), R(2), R(1), U8(1),
B(LdaSmi), U8(1), B(LdaSmi), U8(1),
B(Star), R(1), B(Star), R(1),
B(LdaSmi), U8(1), /* 57 E> */ B(AddSmi), U8(1), R(0),
/* 57 E> */ B(Add), R(0),
B(StaKeyedPropertySloppy), R(2), R(1), U8(1), B(StaKeyedPropertySloppy), R(2), R(1), U8(1),
B(Ldar), R(2), B(Ldar), R(2),
/* 66 S> */ B(Return), /* 66 S> */ B(Return),
...@@ -80,7 +79,7 @@ snippet: " ...@@ -80,7 +79,7 @@ snippet: "
" "
frame size: 5 frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 65 bytecode array length: 64
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1), /* 42 S> */ B(LdaSmi), U8(1),
...@@ -103,8 +102,7 @@ bytecodes: [ ...@@ -103,8 +102,7 @@ bytecodes: [
B(Star), R(4), B(Star), R(4),
B(LdaZero), B(LdaZero),
B(Star), R(3), B(Star), R(3),
B(LdaSmi), U8(2), /* 66 E> */ B(AddSmi), U8(2), R(0),
/* 66 E> */ B(Add), R(0),
B(StaKeyedPropertySloppy), R(4), R(3), U8(3), B(StaKeyedPropertySloppy), R(4), R(3), U8(3),
B(Ldar), R(4), B(Ldar), R(4),
B(StaKeyedPropertySloppy), R(2), R(1), U8(5), B(StaKeyedPropertySloppy), R(2), R(1), U8(5),
......
...@@ -199,7 +199,7 @@ snippet: " ...@@ -199,7 +199,7 @@ snippet: "
" "
frame size: 5 frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 65 bytecode array length: 64
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10), /* 42 S> */ B(LdaSmi), U8(10),
...@@ -211,8 +211,7 @@ bytecodes: [ ...@@ -211,8 +211,7 @@ bytecodes: [
B(Star), R(0), B(Star), R(0),
/* 68 E> */ B(Add), R(2), /* 68 E> */ B(Add), R(2),
B(Star), R(3), B(Star), R(3),
B(LdaSmi), U8(1), /* 76 E> */ B(AddSmi), U8(1), R(0),
/* 76 E> */ B(Add), R(0),
B(Star), R(4), B(Star), R(4),
B(LdaSmi), U8(2), B(LdaSmi), U8(2),
B(Star), R(1), B(Star), R(1),
......
...@@ -65,7 +65,7 @@ snippet: " ...@@ -65,7 +65,7 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 48 bytecode array length: 47
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -74,13 +74,12 @@ bytecodes: [ ...@@ -74,13 +74,12 @@ bytecodes: [
B(Star), R(1), B(Star), R(1),
/* 65 S> */ B(LdaSmi), U8(10), /* 65 S> */ B(LdaSmi), U8(10),
/* 65 E> */ B(TestLessThan), R(0), /* 65 E> */ B(TestLessThan), R(0),
B(JumpIfFalse), U8(33), B(JumpIfFalse), U8(32),
/* 56 E> */ B(StackCheck), /* 56 E> */ B(StackCheck),
/* 75 S> */ B(LdaSmi), U8(12), /* 75 S> */ B(LdaSmi), U8(12),
B(Mul), R(1), B(Mul), R(1),
B(Star), R(1), B(Star), R(1),
/* 89 S> */ B(LdaSmi), U8(1), /* 89 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
/* 102 S> */ B(LdaSmi), U8(3), /* 102 S> */ B(LdaSmi), U8(3),
/* 108 E> */ B(TestEqual), R(0), /* 108 E> */ B(TestEqual), R(0),
...@@ -90,7 +89,7 @@ bytecodes: [ ...@@ -90,7 +89,7 @@ bytecodes: [
/* 132 E> */ B(TestEqual), R(0), /* 132 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 138 S> */ B(Jump), U8(4), /* 138 S> */ B(Jump), U8(4),
B(Jump), U8(-35), B(Jump), U8(-34),
/* 147 S> */ B(Ldar), R(1), /* 147 S> */ B(Ldar), R(1),
/* 157 S> */ B(Return), /* 157 S> */ B(Return),
] ]
...@@ -114,7 +113,7 @@ snippet: " ...@@ -114,7 +113,7 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 55 bytecode array length: 54
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -123,27 +122,26 @@ bytecodes: [ ...@@ -123,27 +122,26 @@ bytecodes: [
/* 62 S> */ B(LdaZero), /* 62 S> */ B(LdaZero),
/* 68 E> */ B(TestLessThan), R(0), /* 68 E> */ B(TestLessThan), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 73 S> */ B(Jump), U8(40), /* 73 S> */ B(Jump), U8(39),
/* 85 S> */ B(LdaSmi), U8(3), /* 85 S> */ B(LdaSmi), U8(3),
/* 91 E> */ B(TestEqual), R(0), /* 91 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 97 S> */ B(Jump), U8(34), /* 97 S> */ B(Jump), U8(33),
/* 106 S> */ B(LdaSmi), U8(4), /* 106 S> */ B(LdaSmi), U8(4),
/* 112 E> */ B(TestEqual), R(0), /* 112 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 118 S> */ B(Jump), U8(26), /* 118 S> */ B(Jump), U8(25),
/* 127 S> */ B(LdaSmi), U8(10), /* 127 S> */ B(LdaSmi), U8(10),
/* 133 E> */ B(TestEqual), R(0), /* 133 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 140 S> */ B(Jump), U8(16), /* 140 S> */ B(Jump), U8(15),
/* 152 S> */ B(LdaSmi), U8(5), /* 152 S> */ B(LdaSmi), U8(5),
/* 158 E> */ B(TestEqual), R(0), /* 158 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 164 S> */ B(Jump), U8(10), /* 164 S> */ B(Jump), U8(9),
/* 173 S> */ B(LdaSmi), U8(1), /* 173 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
B(Jump), U8(-46), B(Jump), U8(-45),
/* 186 S> */ B(Ldar), R(0), /* 186 S> */ B(Ldar), R(0),
/* 196 S> */ B(Return), /* 196 S> */ B(Return),
] ]
...@@ -167,7 +165,7 @@ snippet: " ...@@ -167,7 +165,7 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 41 bytecode array length: 39
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -175,21 +173,19 @@ bytecodes: [ ...@@ -175,21 +173,19 @@ bytecodes: [
/* 45 E> */ B(StackCheck), /* 45 E> */ B(StackCheck),
/* 71 S> */ B(LdaSmi), U8(3), /* 71 S> */ B(LdaSmi), U8(3),
/* 71 E> */ B(TestLessThan), R(0), /* 71 E> */ B(TestLessThan), R(0),
B(JumpIfFalse), U8(19), B(JumpIfFalse), U8(18),
/* 62 E> */ B(StackCheck), /* 62 E> */ B(StackCheck),
/* 82 S> */ B(LdaSmi), U8(2), /* 82 S> */ B(LdaSmi), U8(2),
/* 88 E> */ B(TestEqual), R(0), /* 88 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 94 S> */ B(Jump), U8(10), /* 94 S> */ B(Jump), U8(9),
/* 105 S> */ B(LdaSmi), U8(1), /* 105 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
B(Jump), U8(-21), B(Jump), U8(-20),
/* 122 S> */ B(LdaSmi), U8(1), /* 122 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
/* 135 S> */ B(Jump), U8(4), /* 135 S> */ B(Jump), U8(4),
B(Jump), U8(-32), B(Jump), U8(-30),
/* 144 S> */ B(Ldar), R(0), /* 144 S> */ B(Ldar), R(0),
/* 154 S> */ B(Return), /* 154 S> */ B(Return),
] ]
...@@ -210,7 +206,7 @@ snippet: " ...@@ -210,7 +206,7 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 30
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10), /* 42 S> */ B(LdaSmi), U8(10),
...@@ -218,15 +214,14 @@ bytecodes: [ ...@@ -218,15 +214,14 @@ bytecodes: [
/* 54 S> */ B(LdaSmi), U8(1), /* 54 S> */ B(LdaSmi), U8(1),
B(Star), R(1), B(Star), R(1),
/* 64 S> */ B(Ldar), R(0), /* 64 S> */ B(Ldar), R(0),
B(JumpIfToBooleanFalse), U8(17), B(JumpIfToBooleanFalse), U8(16),
/* 57 E> */ B(StackCheck), /* 57 E> */ B(StackCheck),
/* 71 S> */ B(LdaSmi), U8(12), /* 71 S> */ B(LdaSmi), U8(12),
B(Mul), R(1), B(Mul), R(1),
B(Star), R(1), B(Star), R(1),
/* 85 S> */ B(LdaSmi), U8(1), /* 85 S> */ B(SubSmi), U8(1), R(0),
B(Sub), R(0),
B(Star), R(0), B(Star), R(0),
B(Jump), U8(-17), B(Jump), U8(-16),
/* 98 S> */ B(Ldar), R(1), /* 98 S> */ B(Ldar), R(1),
/* 108 S> */ B(Return), /* 108 S> */ B(Return),
] ]
...@@ -248,7 +243,7 @@ snippet: " ...@@ -248,7 +243,7 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 46 bytecode array length: 45
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -262,17 +257,16 @@ bytecodes: [ ...@@ -262,17 +257,16 @@ bytecodes: [
/* 77 S> */ B(LdaSmi), U8(5), /* 77 S> */ B(LdaSmi), U8(5),
/* 83 E> */ B(TestEqual), R(0), /* 83 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 89 S> */ B(Jump), U8(22), /* 89 S> */ B(Jump), U8(21),
/* 98 S> */ B(LdaSmi), U8(6), /* 98 S> */ B(LdaSmi), U8(6),
/* 104 E> */ B(TestEqual), R(0), /* 104 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 110 S> */ B(Jump), U8(8), /* 110 S> */ B(Jump), U8(7),
/* 122 S> */ B(LdaSmi), U8(1), /* 122 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
/* 144 S> */ B(LdaSmi), U8(10), /* 144 S> */ B(LdaSmi), U8(10),
/* 144 E> */ B(TestLessThan), R(0), /* 144 E> */ B(TestLessThan), R(0),
B(JumpIfTrue), U8(-33), B(JumpIfTrue), U8(-32),
/* 151 S> */ B(Ldar), R(1), /* 151 S> */ B(Ldar), R(1),
/* 161 S> */ B(Return), /* 161 S> */ B(Return),
] ]
...@@ -293,7 +287,7 @@ snippet: " ...@@ -293,7 +287,7 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 29 bytecode array length: 28
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10), /* 42 S> */ B(LdaSmi), U8(10),
...@@ -304,11 +298,10 @@ bytecodes: [ ...@@ -304,11 +298,10 @@ bytecodes: [
/* 64 S> */ B(LdaSmi), U8(12), /* 64 S> */ B(LdaSmi), U8(12),
B(Mul), R(1), B(Mul), R(1),
B(Star), R(1), B(Star), R(1),
/* 78 S> */ B(LdaSmi), U8(1), /* 78 S> */ B(SubSmi), U8(1), R(0),
B(Sub), R(0),
B(Star), R(0), B(Star), R(0),
/* 98 S> */ B(Ldar), R(0), /* 98 S> */ B(Ldar), R(0),
B(JumpIfToBooleanTrue), U8(-15), B(JumpIfToBooleanTrue), U8(-14),
/* 102 S> */ B(Ldar), R(1), /* 102 S> */ B(Ldar), R(1),
/* 112 S> */ B(Return), /* 112 S> */ B(Return),
] ]
...@@ -330,7 +323,7 @@ snippet: " ...@@ -330,7 +323,7 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 40 bytecode array length: 39
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -344,9 +337,8 @@ bytecodes: [ ...@@ -344,9 +337,8 @@ bytecodes: [
/* 77 S> */ B(LdaSmi), U8(5), /* 77 S> */ B(LdaSmi), U8(5),
/* 83 E> */ B(TestEqual), R(0), /* 83 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 89 S> */ B(Jump), U8(16), /* 89 S> */ B(Jump), U8(15),
/* 98 S> */ B(LdaSmi), U8(1), /* 98 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
/* 111 S> */ B(LdaSmi), U8(6), /* 111 S> */ B(LdaSmi), U8(6),
/* 117 E> */ B(TestEqual), R(0), /* 117 E> */ B(TestEqual), R(0),
...@@ -373,7 +365,7 @@ snippet: " ...@@ -373,7 +365,7 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 42 bytecode array length: 41
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -387,15 +379,14 @@ bytecodes: [ ...@@ -387,15 +379,14 @@ bytecodes: [
/* 77 S> */ B(LdaSmi), U8(5), /* 77 S> */ B(LdaSmi), U8(5),
/* 83 E> */ B(TestEqual), R(0), /* 83 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 89 S> */ B(Jump), U8(18), /* 89 S> */ B(Jump), U8(17),
/* 98 S> */ B(LdaSmi), U8(1), /* 98 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
/* 111 S> */ B(LdaSmi), U8(6), /* 111 S> */ B(LdaSmi), U8(6),
/* 117 E> */ B(TestEqual), R(0), /* 117 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 123 S> */ B(Jump), U8(2), /* 123 S> */ B(Jump), U8(2),
B(Jump), U8(-29), B(Jump), U8(-28),
/* 149 S> */ B(Ldar), R(1), /* 149 S> */ B(Ldar), R(1),
/* 159 S> */ B(Return), /* 159 S> */ B(Return),
] ]
...@@ -415,7 +406,7 @@ snippet: " ...@@ -415,7 +406,7 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 30
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -424,15 +415,14 @@ bytecodes: [ ...@@ -424,15 +415,14 @@ bytecodes: [
/* 58 S> */ B(LdaSmi), U8(1), /* 58 S> */ B(LdaSmi), U8(1),
/* 64 E> */ B(TestEqual), R(0), /* 64 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 70 S> */ B(Jump), U8(18), /* 70 S> */ B(Jump), U8(17),
/* 79 S> */ B(LdaSmi), U8(2), /* 79 S> */ B(LdaSmi), U8(2),
/* 85 E> */ B(TestEqual), R(0), /* 85 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 91 S> */ B(Jump), U8(8), /* 91 S> */ B(Jump), U8(7),
/* 103 S> */ B(LdaSmi), U8(1), /* 103 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
B(Jump), U8(-23), B(Jump), U8(-22),
B(LdaUndefined), B(LdaUndefined),
/* 116 S> */ B(Return), /* 116 S> */ B(Return),
] ]
...@@ -451,7 +441,7 @@ snippet: " ...@@ -451,7 +441,7 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 30
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 47 S> */ B(LdaZero), /* 47 S> */ B(LdaZero),
...@@ -460,15 +450,14 @@ bytecodes: [ ...@@ -460,15 +450,14 @@ bytecodes: [
/* 56 S> */ B(LdaSmi), U8(1), /* 56 S> */ B(LdaSmi), U8(1),
/* 62 E> */ B(TestEqual), R(0), /* 62 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 68 S> */ B(Jump), U8(18), /* 68 S> */ B(Jump), U8(17),
/* 77 S> */ B(LdaSmi), U8(2), /* 77 S> */ B(LdaSmi), U8(2),
/* 83 E> */ B(TestEqual), R(0), /* 83 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 89 S> */ B(Jump), U8(8), /* 89 S> */ B(Jump), U8(7),
/* 101 S> */ B(LdaSmi), U8(1), /* 101 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
B(Jump), U8(-23), B(Jump), U8(-22),
B(LdaUndefined), B(LdaUndefined),
/* 114 S> */ B(Return), /* 114 S> */ B(Return),
] ]
...@@ -487,7 +476,7 @@ snippet: " ...@@ -487,7 +476,7 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 30
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -496,15 +485,14 @@ bytecodes: [ ...@@ -496,15 +485,14 @@ bytecodes: [
/* 68 S> */ B(LdaSmi), U8(1), /* 68 S> */ B(LdaSmi), U8(1),
/* 74 E> */ B(TestEqual), R(0), /* 74 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 80 S> */ B(Jump), U8(18), /* 80 S> */ B(Jump), U8(17),
/* 89 S> */ B(LdaSmi), U8(2), /* 89 S> */ B(LdaSmi), U8(2),
/* 95 E> */ B(TestEqual), R(0), /* 95 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 101 S> */ B(Jump), U8(2), /* 101 S> */ B(Jump), U8(2),
/* 55 S> */ B(LdaSmi), U8(1), /* 55 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
B(Jump), U8(-23), B(Jump), U8(-22),
B(LdaUndefined), B(LdaUndefined),
/* 113 S> */ B(Return), /* 113 S> */ B(Return),
] ]
...@@ -522,7 +510,7 @@ snippet: " ...@@ -522,7 +510,7 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 30
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 47 S> */ B(LdaZero), /* 47 S> */ B(LdaZero),
...@@ -531,15 +519,14 @@ bytecodes: [ ...@@ -531,15 +519,14 @@ bytecodes: [
/* 66 S> */ B(LdaSmi), U8(1), /* 66 S> */ B(LdaSmi), U8(1),
/* 72 E> */ B(TestEqual), R(0), /* 72 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 78 S> */ B(Jump), U8(18), /* 78 S> */ B(Jump), U8(17),
/* 87 S> */ B(LdaSmi), U8(2), /* 87 S> */ B(LdaSmi), U8(2),
/* 93 E> */ B(TestEqual), R(0), /* 93 E> */ B(TestEqual), R(0),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
/* 99 S> */ B(Jump), U8(2), /* 99 S> */ B(Jump), U8(2),
/* 53 S> */ B(LdaSmi), U8(1), /* 53 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
B(Jump), U8(-23), B(Jump), U8(-22),
B(LdaUndefined), B(LdaUndefined),
/* 111 S> */ B(Return), /* 111 S> */ B(Return),
] ]
...@@ -558,7 +545,7 @@ snippet: " ...@@ -558,7 +545,7 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 32 bytecode array length: 30
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -567,16 +554,14 @@ bytecodes: [ ...@@ -567,16 +554,14 @@ bytecodes: [
B(Star), R(1), B(Star), R(1),
/* 63 S> */ B(LdaSmi), U8(100), /* 63 S> */ B(LdaSmi), U8(100),
/* 63 E> */ B(TestLessThan), R(1), /* 63 E> */ B(TestLessThan), R(1),
B(JumpIfFalse), U8(19), B(JumpIfFalse), U8(17),
/* 45 E> */ B(StackCheck), /* 45 E> */ B(StackCheck),
/* 85 S> */ B(LdaSmi), U8(1), /* 85 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
/* 98 S> */ B(Jump), U8(2), /* 98 S> */ B(Jump), U8(2),
/* 72 S> */ B(LdaSmi), U8(1), /* 72 S> */ B(AddSmi), U8(1), R(1),
B(Add), R(1),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(-21), B(Jump), U8(-19),
B(LdaUndefined), B(LdaUndefined),
/* 110 S> */ B(Return), /* 110 S> */ B(Return),
] ]
...@@ -656,7 +641,7 @@ snippet: " ...@@ -656,7 +641,7 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 32 bytecode array length: 31
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -664,8 +649,7 @@ bytecodes: [ ...@@ -664,8 +649,7 @@ bytecodes: [
/* 58 S> */ B(LdaZero), /* 58 S> */ B(LdaZero),
B(Star), R(1), B(Star), R(1),
/* 45 E> */ B(StackCheck), /* 45 E> */ B(StackCheck),
/* 76 S> */ B(LdaSmi), U8(1), /* 76 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
/* 89 S> */ B(LdaSmi), U8(20), /* 89 S> */ B(LdaSmi), U8(20),
/* 95 E> */ B(TestEqual), R(0), /* 95 E> */ B(TestEqual), R(0),
...@@ -674,7 +658,7 @@ bytecodes: [ ...@@ -674,7 +658,7 @@ bytecodes: [
/* 69 S> */ B(Ldar), R(1), /* 69 S> */ B(Ldar), R(1),
B(Inc), B(Inc),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(-20), B(Jump), U8(-19),
/* 112 S> */ B(Ldar), R(0), /* 112 S> */ B(Ldar), R(0),
/* 122 S> */ B(Return), /* 122 S> */ B(Return),
] ]
......
...@@ -19,13 +19,12 @@ snippet: " ...@@ -19,13 +19,12 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 15 bytecode array length: 14
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
B(Star), R(0), B(Star), R(0),
/* 56 S> */ B(LdaSmi), U8(1), /* 56 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
/* 69 S> */ B(Jump), U8(2), /* 69 S> */ B(Jump), U8(2),
/* 97 S> */ B(Ldar), R(0), /* 97 S> */ B(Ldar), R(0),
......
...@@ -24,7 +24,7 @@ snippet: " ...@@ -24,7 +24,7 @@ snippet: "
" "
frame size: 7 frame size: 7
parameter count: 1 parameter count: 1
bytecode array length: 54 bytecode array length: 53
bytecodes: [ bytecodes: [
B(Mov), R(closure), R(0), B(Mov), R(closure), R(0),
/* 99 E> */ B(StackCheck), /* 99 E> */ B(StackCheck),
...@@ -44,8 +44,7 @@ bytecodes: [ ...@@ -44,8 +44,7 @@ bytecodes: [
B(Star), R(1), B(Star), R(1),
/* 117 E> */ B(Call), R(1), R(2), U8(1), U8(1), /* 117 E> */ B(Call), R(1), R(2), U8(1), U8(1),
B(Star), R(3), B(Star), R(3),
B(LdaSmi), U8(1), B(AddSmi), U8(1), R(3),
B(Add), R(3),
/* 131 S> */ B(Return), /* 131 S> */ B(Return),
] ]
constant pool: [ constant pool: [
......
...@@ -13,13 +13,12 @@ snippet: " ...@@ -13,13 +13,12 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 16 bytecode array length: 15
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1), /* 42 S> */ B(LdaSmi), U8(1),
B(Star), R(0), B(Star), R(0),
/* 45 S> */ B(LdaSmi), U8(2), /* 45 S> */ B(AddSmi), U8(2), R(0),
B(Add), R(0),
B(Mov), R(0), R(1), B(Mov), R(0), R(1),
B(Star), R(0), B(Star), R(0),
B(LdaUndefined), B(LdaUndefined),
...@@ -112,7 +111,7 @@ snippet: " ...@@ -112,7 +111,7 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 29 bytecode array length: 28
bytecodes: [ bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1), B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(PushContext), R(0), B(PushContext), R(0),
...@@ -121,8 +120,7 @@ bytecodes: [ ...@@ -121,8 +120,7 @@ bytecodes: [
/* 42 E> */ B(StaContextSlot), R(context), U8(4), /* 42 E> */ B(StaContextSlot), R(context), U8(4),
/* 45 S> */ B(CreateClosure), U8(0), U8(2), /* 45 S> */ B(CreateClosure), U8(0), U8(2),
/* 75 S> */ B(LdrContextSlot), R(context), U8(4), R(1), /* 75 S> */ B(LdrContextSlot), R(context), U8(4), R(1),
B(LdaSmi), U8(24), B(BitwiseOrSmi), U8(24), R(1),
B(BitwiseOr), R(1),
/* 77 E> */ B(StaContextSlot), R(context), U8(4), /* 77 E> */ B(StaContextSlot), R(context), U8(4),
B(LdaUndefined), B(LdaUndefined),
/* 84 S> */ B(Return), /* 84 S> */ B(Return),
......
...@@ -16,12 +16,11 @@ snippet: " ...@@ -16,12 +16,11 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 12 bytecode array length: 11
bytecodes: [ bytecodes: [
/* 26 E> */ B(StackCheck), /* 26 E> */ B(StackCheck),
/* 31 S> */ B(LdrGlobal), U8(1), R(0), /* 31 S> */ B(LdrGlobal), U8(1), R(0),
B(LdaSmi), U8(1), B(BitwiseAndSmi), U8(1), R(0),
B(BitwiseAnd), R(0),
/* 45 E> */ B(StaGlobalSloppy), U8(0), U8(3), /* 45 E> */ B(StaGlobalSloppy), U8(0), U8(3),
/* 51 S> */ B(Return), /* 51 S> */ B(Return),
] ]
...@@ -39,12 +38,11 @@ snippet: " ...@@ -39,12 +38,11 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 12 bytecode array length: 11
bytecodes: [ bytecodes: [
/* 27 E> */ B(StackCheck), /* 27 E> */ B(StackCheck),
/* 32 S> */ B(LdrGlobal), U8(1), R(0), /* 32 S> */ B(LdrGlobal), U8(1), R(0),
B(LdaSmi), U8(1), B(AddSmi), U8(1), R(0),
B(Add), R(0),
/* 51 E> */ B(StaGlobalSloppy), U8(0), U8(3), /* 51 E> */ B(StaGlobalSloppy), U8(0), U8(3),
/* 57 S> */ B(Return), /* 57 S> */ B(Return),
] ]
......
...@@ -116,14 +116,13 @@ snippet: " ...@@ -116,14 +116,13 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 23 bytecode array length: 22
bytecodes: [ bytecodes: [
/* 10 E> */ B(StackCheck), /* 10 E> */ B(StackCheck),
/* 25 S> */ B(LdaSmi), U8(1), /* 25 S> */ B(LdaSmi), U8(1),
B(Star), R(0), B(Star), R(0),
/* 30 S> */ B(JumpIfToBooleanFalse), U8(13), /* 30 S> */ B(JumpIfToBooleanFalse), U8(12),
/* 43 S> */ B(LdaSmi), U8(1), /* 43 S> */ B(AddSmi), U8(1), R(0),
B(Add), R(0),
B(Mov), R(0), R(1), B(Mov), R(0), R(1),
B(Star), R(0), B(Star), R(0),
B(Jump), U8(5), B(Jump), U8(5),
......
...@@ -76,15 +76,14 @@ snippet: " ...@@ -76,15 +76,14 @@ snippet: "
" "
frame size: 2 frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 22 bytecode array length: 21
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1), /* 42 S> */ B(LdaSmi), U8(1),
B(Star), R(0), B(Star), R(0),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), /* 45 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1),
B(Star), R(1), B(Star), R(1),
B(LdaSmi), U8(1), /* 67 E> */ B(AddSmi), U8(1), R(0),
/* 67 E> */ B(Add), R(0),
B(StaNamedPropertySloppy), R(1), U8(1), U8(1), B(StaNamedPropertySloppy), R(1), U8(1), U8(1),
B(Ldar), R(1), B(Ldar), R(1),
/* 76 S> */ B(Return), /* 76 S> */ B(Return),
......
...@@ -32,13 +32,12 @@ snippet: " ...@@ -32,13 +32,12 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 9 bytecode array length: 8
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
B(Star), R(0), B(Star), R(0),
/* 45 S> */ B(LdaSmi), U8(3), /* 45 S> */ B(AddSmi), U8(3), R(0),
B(Add), R(0),
/* 59 S> */ B(Return), /* 59 S> */ B(Return),
] ]
constant pool: [ constant pool: [
...@@ -52,13 +51,12 @@ snippet: " ...@@ -52,13 +51,12 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 9 bytecode array length: 8
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
B(Star), R(0), B(Star), R(0),
/* 45 S> */ B(LdaSmi), U8(3), /* 45 S> */ B(SubSmi), U8(3), R(0),
B(Sub), R(0),
/* 59 S> */ B(Return), /* 59 S> */ B(Return),
] ]
constant pool: [ constant pool: [
...@@ -132,13 +130,12 @@ snippet: " ...@@ -132,13 +130,12 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 10 bytecode array length: 9
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1), /* 42 S> */ B(LdaSmi), U8(1),
B(Star), R(0), B(Star), R(0),
/* 45 S> */ B(LdaSmi), U8(2), /* 45 S> */ B(BitwiseOrSmi), U8(2), R(0),
B(BitwiseOr), R(0),
/* 59 S> */ B(Return), /* 59 S> */ B(Return),
] ]
constant pool: [ constant pool: [
...@@ -172,13 +169,12 @@ snippet: " ...@@ -172,13 +169,12 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 10 bytecode array length: 9
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1), /* 42 S> */ B(LdaSmi), U8(1),
B(Star), R(0), B(Star), R(0),
/* 45 S> */ B(LdaSmi), U8(2), /* 45 S> */ B(BitwiseAndSmi), U8(2), R(0),
B(BitwiseAnd), R(0),
/* 59 S> */ B(Return), /* 59 S> */ B(Return),
] ]
constant pool: [ constant pool: [
...@@ -192,13 +188,12 @@ snippet: " ...@@ -192,13 +188,12 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 10 bytecode array length: 9
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10), /* 42 S> */ B(LdaSmi), U8(10),
B(Star), R(0), B(Star), R(0),
/* 46 S> */ B(LdaSmi), U8(3), /* 46 S> */ B(ShiftLeftSmi), U8(3), R(0),
B(ShiftLeft), R(0),
/* 61 S> */ B(Return), /* 61 S> */ B(Return),
] ]
constant pool: [ constant pool: [
...@@ -212,13 +207,12 @@ snippet: " ...@@ -212,13 +207,12 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 10 bytecode array length: 9
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10), /* 42 S> */ B(LdaSmi), U8(10),
B(Star), R(0), B(Star), R(0),
/* 46 S> */ B(LdaSmi), U8(3), /* 46 S> */ B(ShiftRightSmi), U8(3), R(0),
B(ShiftRight), R(0),
/* 61 S> */ B(Return), /* 61 S> */ B(Return),
] ]
constant pool: [ constant pool: [
......
...@@ -481,7 +481,7 @@ snippet: " ...@@ -481,7 +481,7 @@ snippet: "
" "
frame size: 5 frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 59 bytecode array length: 58
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1), /* 42 S> */ B(LdaSmi), U8(1),
...@@ -493,10 +493,9 @@ bytecodes: [ ...@@ -493,10 +493,9 @@ bytecodes: [
B(JumpIfToBooleanTrue), U8(10), B(JumpIfToBooleanTrue), U8(10),
B(LdaSmi), U8(2), B(LdaSmi), U8(2),
B(TestEqualStrict), R(3), B(TestEqualStrict), R(3),
B(JumpIfTrue), U8(33), B(JumpIfTrue), U8(32),
B(Jump), U8(35), B(Jump), U8(34),
B(LdaSmi), U8(1), /* 77 E> */ B(AddSmi), U8(1), R(2),
/* 77 E> */ B(Add), R(2),
B(Star), R(1), B(Star), R(1),
/* 70 S> */ B(LdaSmi), U8(2), /* 70 S> */ B(LdaSmi), U8(2),
B(TestEqualStrict), R(1), B(TestEqualStrict), R(1),
......
...@@ -17,7 +17,7 @@ snippet: " ...@@ -17,7 +17,7 @@ snippet: "
" "
frame size: 1 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 23 bytecode array length: 22
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero), /* 42 S> */ B(LdaZero),
...@@ -25,12 +25,11 @@ bytecodes: [ ...@@ -25,12 +25,11 @@ bytecodes: [
/* 54 S> */ B(LdaSmi), U8(10), /* 54 S> */ B(LdaSmi), U8(10),
/* 54 E> */ B(TestEqual), R(0), /* 54 E> */ B(TestEqual), R(0),
B(LogicalNot), B(LogicalNot),
B(JumpIfFalse), U8(11), B(JumpIfFalse), U8(10),
/* 45 E> */ B(StackCheck), /* 45 E> */ B(StackCheck),
/* 65 S> */ B(LdaSmi), U8(10), /* 65 S> */ B(AddSmi), U8(10), R(0),
B(Add), R(0),
B(Star), R(0), B(Star), R(0),
B(Jump), U8(-14), B(Jump), U8(-13),
/* 79 S> */ B(Ldar), R(0), /* 79 S> */ B(Ldar), R(0),
/* 89 S> */ B(Return), /* 89 S> */ B(Return),
] ]
...@@ -99,7 +98,7 @@ snippet: " ...@@ -99,7 +98,7 @@ snippet: "
" "
frame size: 4 frame size: 4
parameter count: 1 parameter count: 1
bytecode array length: 22 bytecode array length: 21
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(Wide), B(LdaSmi), U16(1234), /* 42 S> */ B(Wide), B(LdaSmi), U16(1234),
...@@ -107,8 +106,7 @@ bytecodes: [ ...@@ -107,8 +106,7 @@ bytecodes: [
/* 56 S> */ B(Nop), /* 56 S> */ B(Nop),
/* 66 E> */ B(Mul), R(0), /* 66 E> */ B(Mul), R(0),
B(Star), R(3), B(Star), R(3),
B(LdaSmi), U8(1), B(SubSmi), U8(1), R(3),
B(Sub), R(3),
B(LdrUndefined), R(1), B(LdrUndefined), R(1),
B(Ldar), R(1), B(Ldar), R(1),
/* 74 S> */ B(Nop), /* 74 S> */ B(Nop),
......
...@@ -42,6 +42,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -42,6 +42,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
builder.LoadLiteral(Smi::FromInt(0)) builder.LoadLiteral(Smi::FromInt(0))
.StoreAccumulatorInRegister(reg) .StoreAccumulatorInRegister(reg)
.LoadLiteral(Smi::FromInt(8)) .LoadLiteral(Smi::FromInt(8))
.CompareOperation(Token::Value::NE, reg) // Prevent peephole optimization
// LdaSmi, Star -> LdrSmi.
.StoreAccumulatorInRegister(reg) .StoreAccumulatorInRegister(reg)
.LoadLiteral(Smi::FromInt(10000000)) .LoadLiteral(Smi::FromInt(10000000))
.StoreAccumulatorInRegister(reg) .StoreAccumulatorInRegister(reg)
...@@ -136,6 +138,20 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -136,6 +138,20 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.BinaryOperation(Token::Value::SAR, reg) .BinaryOperation(Token::Value::SAR, reg)
.BinaryOperation(Token::Value::SHR, reg); .BinaryOperation(Token::Value::SHR, reg);
// Emit peephole optimizations of LdaSmi followed by binary operation.
builder.LoadLiteral(Smi::FromInt(1))
.BinaryOperation(Token::Value::ADD, reg)
.LoadLiteral(Smi::FromInt(2))
.BinaryOperation(Token::Value::SUB, reg)
.LoadLiteral(Smi::FromInt(3))
.BinaryOperation(Token::Value::BIT_AND, reg)
.LoadLiteral(Smi::FromInt(4))
.BinaryOperation(Token::Value::BIT_OR, reg)
.LoadLiteral(Smi::FromInt(5))
.BinaryOperation(Token::Value::SHL, reg)
.LoadLiteral(Smi::FromInt(6))
.BinaryOperation(Token::Value::SAR, reg);
// Emit count operatior invocations // Emit count operatior invocations
builder.CountOperation(Token::Value::ADD).CountOperation(Token::Value::SUB); builder.CountOperation(Token::Value::ADD).CountOperation(Token::Value::SUB);
...@@ -399,6 +415,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -399,6 +415,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
scorecard[Bytecodes::ToByte(Bytecode::kJumpIfFalse)] = 1; scorecard[Bytecodes::ToByte(Bytecode::kJumpIfFalse)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kJumpIfTrueConstant)] = 1; scorecard[Bytecodes::ToByte(Bytecode::kJumpIfTrueConstant)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kJumpIfFalseConstant)] = 1; scorecard[Bytecodes::ToByte(Bytecode::kJumpIfFalseConstant)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kAddSmi)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kSubSmi)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kBitwiseAndSmi)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kBitwiseOrSmi)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kShiftLeftSmi)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kShiftRightSmi)] = 1;
} }
// Check return occurs at the end and only once in the BytecodeArray. // Check return occurs at the end and only once in the BytecodeArray.
......
...@@ -43,8 +43,10 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) { ...@@ -43,8 +43,10 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
.LoadLiteral(zero) .LoadLiteral(zero)
.StoreAccumulatorInRegister(reg_0) .StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_0) .LoadLiteral(smi_0)
.StackCheck(0)
.StoreAccumulatorInRegister(reg_0) .StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_1) .LoadLiteral(smi_1)
.StackCheck(1)
.StoreAccumulatorInRegister(reg_1) .StoreAccumulatorInRegister(reg_1)
.LoadAccumulatorWithRegister(reg_0) .LoadAccumulatorWithRegister(reg_0)
.BinaryOperation(Token::Value::ADD, reg_0) .BinaryOperation(Token::Value::ADD, reg_0)
...@@ -122,6 +124,14 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) { ...@@ -122,6 +124,14 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle); offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
iterator.Advance(); iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
CHECK_EQ(iterator.current_offset(), offset);
CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
CHECK_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
CHECK(!iterator.done());
offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar); CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
CHECK_EQ(iterator.current_offset(), offset); CHECK_EQ(iterator.current_offset(), offset);
CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
...@@ -140,6 +150,14 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) { ...@@ -140,6 +150,14 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
kPrefixByteSize; kPrefixByteSize;
iterator.Advance(); iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
CHECK_EQ(iterator.current_offset(), offset);
CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
CHECK_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
CHECK(!iterator.done());
offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar); CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
CHECK_EQ(iterator.current_offset(), offset); CHECK_EQ(iterator.current_offset(), offset);
CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
......
...@@ -24,6 +24,11 @@ class BytecodePeepholeOptimizerTest : public BytecodePipelineStage, ...@@ -24,6 +24,11 @@ class BytecodePeepholeOptimizerTest : public BytecodePipelineStage,
peephole_optimizer_(&constant_array_builder_, this) {} peephole_optimizer_(&constant_array_builder_, this) {}
~BytecodePeepholeOptimizerTest() override {} ~BytecodePeepholeOptimizerTest() override {}
void Reset() {
last_written_.set_bytecode(Bytecode::kIllegal);
write_count_ = 0;
}
void Write(BytecodeNode* node) override { void Write(BytecodeNode* node) override {
write_count_++; write_count_++;
last_written_.Clone(node); last_written_.Clone(node);
...@@ -489,6 +494,84 @@ TEST_F(BytecodePeepholeOptimizerTest, MergeLdaUndefinedStar) { ...@@ -489,6 +494,84 @@ TEST_F(BytecodePeepholeOptimizerTest, MergeLdaUndefinedStar) {
CHECK_EQ(last_written().bytecode(), third.bytecode()); CHECK_EQ(last_written().bytecode(), third.bytecode());
} }
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaSmiWithBinaryOp) {
Bytecode operator_replacement_pairs[][2] = {
{Bytecode::kAdd, Bytecode::kAddSmi},
{Bytecode::kSub, Bytecode::kSubSmi},
{Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi},
{Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi},
{Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi},
{Bytecode::kShiftRight, Bytecode::kShiftRightSmi}};
for (auto operator_replacement : operator_replacement_pairs) {
uint32_t imm_operand = 17;
BytecodeNode first(Bytecode::kLdaSmi, imm_operand);
first.source_info().Clone({3, true});
uint32_t reg_operand = Register(0).ToOperand();
BytecodeNode second(operator_replacement[0], reg_operand);
optimizer()->Write(&first);
optimizer()->Write(&second);
Flush();
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written().bytecode(), operator_replacement[1]);
CHECK_EQ(last_written().operand_count(), 2);
CHECK_EQ(last_written().operand(0), imm_operand);
CHECK_EQ(last_written().operand(1), reg_operand);
CHECK_EQ(last_written().source_info(), first.source_info());
Reset();
}
}
TEST_F(BytecodePeepholeOptimizerTest, NotMergingLdaSmiWithBinaryOp) {
Bytecode operator_replacement_pairs[][2] = {
{Bytecode::kAdd, Bytecode::kAddSmi},
{Bytecode::kSub, Bytecode::kSubSmi},
{Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi},
{Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi},
{Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi},
{Bytecode::kShiftRight, Bytecode::kShiftRightSmi}};
for (auto operator_replacement : operator_replacement_pairs) {
uint32_t imm_operand = 17;
BytecodeNode first(Bytecode::kLdaSmi, imm_operand);
first.source_info().Clone({3, true});
uint32_t reg_operand = Register(0).ToOperand();
BytecodeNode second(operator_replacement[0], reg_operand);
second.source_info().Clone({4, true});
optimizer()->Write(&first);
optimizer()->Write(&second);
CHECK_EQ(last_written(), first);
Flush();
CHECK_EQ(last_written(), second);
Reset();
}
}
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaZeroWithBinaryOp) {
Bytecode operator_replacement_pairs[][2] = {
{Bytecode::kAdd, Bytecode::kAddSmi},
{Bytecode::kSub, Bytecode::kSubSmi},
{Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi},
{Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi},
{Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi},
{Bytecode::kShiftRight, Bytecode::kShiftRightSmi}};
for (auto operator_replacement : operator_replacement_pairs) {
BytecodeNode first(Bytecode::kLdaZero);
uint32_t reg_operand = Register(0).ToOperand();
BytecodeNode second(operator_replacement[0], reg_operand);
optimizer()->Write(&first);
optimizer()->Write(&second);
Flush();
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written().bytecode(), operator_replacement[1]);
CHECK_EQ(last_written().operand_count(), 2);
CHECK_EQ(last_written().operand(0), 0);
CHECK_EQ(last_written().operand(1), reg_operand);
Reset();
}
}
} // namespace interpreter } // namespace interpreter
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
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