Commit e56437b6 authored by leszeks's avatar leszeks Committed by Commit bot

[ignition] Use absolute values for jump offsets

Since JumpLoop is always backwards, and other jumps are always forwards,
we can store the jump offset as an always positive integer and decide on
the jump direction based on the bytecode. This will save a small amount
of space for large-ish for loops (>128 bytecodes).

Review-Url: https://codereview.chromium.org/2641443002
Cr-Commit-Position: refs/heads/master@{#42638}
parent 82631263
......@@ -178,7 +178,10 @@ Handle<Object> BytecodeArrayAccessor::GetConstantForIndexOperand(
int BytecodeArrayAccessor::GetJumpTargetOffset() const {
Bytecode bytecode = current_bytecode();
if (interpreter::Bytecodes::IsJumpImmediate(bytecode)) {
int relative_offset = GetImmediateOperand(0);
int relative_offset = GetUnsignedImmediateOperand(0);
if (bytecode == Bytecode::kJumpLoop) {
relative_offset = -relative_offset;
}
return current_offset() + relative_offset + current_prefix_offset();
} else if (interpreter::Bytecodes::IsJumpConstant(bytecode)) {
Smi* smi = Smi::cast(*GetConstantForIndexOperand(0));
......
......@@ -707,6 +707,7 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
}
BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
DCHECK(!label->is_bound());
OutputJump(label, 0);
return *this;
}
......@@ -714,40 +715,47 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) {
// The peephole optimizer attempts to simplify JumpIfToBooleanTrue
// to JumpIfTrue.
DCHECK(!label->is_bound());
OutputJumpIfToBooleanTrue(label, 0);
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) {
DCHECK(!label->is_bound());
OutputJumpIfToBooleanFalse(label, 0);
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) {
DCHECK(!label->is_bound());
OutputJumpIfNull(label, 0);
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined(
BytecodeLabel* label) {
DCHECK(!label->is_bound());
OutputJumpIfUndefined(label, 0);
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
BytecodeLabel* label) {
DCHECK(!label->is_bound());
OutputJumpIfNotHole(label, 0);
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfJSReceiver(
BytecodeLabel* label) {
DCHECK(!label->is_bound());
OutputJumpIfJSReceiver(label, 0);
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label,
int loop_depth) {
DCHECK(label->is_bound());
OutputJumpLoop(label, 0, loop_depth);
return *this;
}
......
......@@ -175,16 +175,19 @@ Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) {
void BytecodeArrayWriter::PatchJumpWith8BitOperand(size_t jump_location,
int delta) {
Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes()->at(jump_location));
DCHECK(Bytecodes::IsForwardJump(jump_bytecode));
DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
DCHECK_EQ(Bytecodes::GetOperandType(jump_bytecode, 0), OperandType::kUImm);
DCHECK_GT(delta, 0);
size_t operand_location = jump_location + 1;
DCHECK_EQ(bytecodes()->at(operand_location), k8BitJumpPlaceholder);
if (Bytecodes::ScaleForSignedOperand(delta) == OperandScale::kSingle) {
// The jump fits within the range of an Imm8 operand, so cancel
if (Bytecodes::ScaleForUnsignedOperand(delta) == OperandScale::kSingle) {
// The jump fits within the range of an UImm8 operand, so cancel
// the reservation and jump directly.
constant_array_builder()->DiscardReservedEntry(OperandSize::kByte);
bytecodes()->at(operand_location) = static_cast<uint8_t>(delta);
} else {
// The jump does not fit within the range of an Imm8 operand, so
// The jump does not fit within the range of an UImm8 operand, so
// commit reservation putting the offset into the constant pool,
// and update the jump instruction and operand.
size_t entry = constant_array_builder()->CommitReservedEntry(
......@@ -200,10 +203,13 @@ void BytecodeArrayWriter::PatchJumpWith8BitOperand(size_t jump_location,
void BytecodeArrayWriter::PatchJumpWith16BitOperand(size_t jump_location,
int delta) {
Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes()->at(jump_location));
DCHECK(Bytecodes::IsForwardJump(jump_bytecode));
DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
DCHECK_EQ(Bytecodes::GetOperandType(jump_bytecode, 0), OperandType::kUImm);
DCHECK_GT(delta, 0);
size_t operand_location = jump_location + 1;
uint8_t operand_bytes[2];
if (Bytecodes::ScaleForSignedOperand(delta) <= OperandScale::kDouble) {
if (Bytecodes::ScaleForUnsignedOperand(delta) <= OperandScale::kDouble) {
// The jump fits within the range of an Imm16 operand, so cancel
// the reservation and jump directly.
constant_array_builder()->DiscardReservedEntry(OperandSize::kShort);
......@@ -282,15 +288,13 @@ void BytecodeArrayWriter::EmitJump(BytecodeNode* node, BytecodeLabel* label) {
if (label->is_bound()) {
CHECK_GE(current_offset, label->offset());
CHECK_LE(current_offset, static_cast<size_t>(kMaxInt));
CHECK_LE(current_offset, static_cast<size_t>(kMaxUInt32));
// Label has been bound already so this is a backwards jump.
size_t abs_delta = current_offset - label->offset();
int delta = -static_cast<int>(abs_delta);
OperandScale operand_scale = Bytecodes::ScaleForSignedOperand(delta);
uint32_t delta = static_cast<uint32_t>(current_offset - label->offset());
OperandScale operand_scale = Bytecodes::ScaleForUnsignedOperand(delta);
if (operand_scale > OperandScale::kSingle) {
// Adjust for scaling byte prefix for wide jump offset.
DCHECK_LE(delta, 0);
delta -= 1;
delta += 1;
}
DCHECK_EQ(Bytecode::kJumpLoop, node->bytecode());
node->update_operand0(delta);
......
......@@ -228,9 +228,9 @@ namespace interpreter {
\
/* Control Flow -- carefully ordered for efficient checks */ \
/* - [Unconditional jumps] */ \
V(JumpLoop, AccumulatorUse::kNone, OperandType::kImm, OperandType::kImm) \
V(JumpLoop, AccumulatorUse::kNone, OperandType::kUImm, OperandType::kImm) \
/* - [Forward jumps] */ \
V(Jump, AccumulatorUse::kNone, OperandType::kImm) \
V(Jump, AccumulatorUse::kNone, OperandType::kUImm) \
/* - [Start constant jumps] */ \
V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \
/* - [Conditional jumps] */ \
......@@ -246,15 +246,15 @@ namespace interpreter {
V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \
/* - [End constant jumps] */ \
/* - [Conditional immediate jumps] */ \
V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kImm) \
V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kImm) \
V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kUImm) \
V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kUImm) \
/* - [End ToBoolean jumps] */ \
V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kImm) \
V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kImm) \
V(JumpIfNull, AccumulatorUse::kRead, OperandType::kImm) \
V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kImm) \
V(JumpIfJSReceiver, AccumulatorUse::kRead, OperandType::kImm) \
V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm) \
V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kUImm) \
V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kUImm) \
V(JumpIfNull, AccumulatorUse::kRead, OperandType::kUImm) \
V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kUImm) \
V(JumpIfJSReceiver, AccumulatorUse::kRead, OperandType::kUImm) \
V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kUImm) \
\
/* Complex flow control For..in */ \
V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg, \
......
......@@ -395,6 +395,10 @@ Node* InterpreterAssembler::BytecodeOperandUImm(int operand_index) {
return BytecodeUnsignedOperand(operand_index, operand_size);
}
Node* InterpreterAssembler::BytecodeOperandUImmWord(int operand_index) {
return ChangeUint32ToWord(BytecodeOperandUImm(operand_index));
}
Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) {
DCHECK_EQ(OperandType::kImm,
Bytecodes::GetOperandType(bytecode_, operand_index));
......@@ -882,10 +886,7 @@ Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context,
arg_count, first_arg, function_entry);
}
void InterpreterAssembler::UpdateInterruptBudget(Node* weight) {
// TODO(rmcilroy): It might be worthwhile to only update the budget for
// backwards branches. Those are distinguishable by the {JumpLoop} bytecode.
void InterpreterAssembler::UpdateInterruptBudget(Node* weight, bool backward) {
Label ok(this), interrupt_check(this, Label::kDeferred), end(this);
Node* budget_offset =
IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag);
......@@ -894,7 +895,11 @@ void InterpreterAssembler::UpdateInterruptBudget(Node* weight) {
Variable new_budget(this, MachineRepresentation::kWord32);
Node* old_budget =
Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset);
new_budget.Bind(Int32Add(old_budget, weight));
if (backward) {
new_budget.Bind(Int32Sub(old_budget, weight));
} else {
new_budget.Bind(Int32Add(old_budget, weight));
}
Node* condition =
Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0));
Branch(condition, &ok, &interrupt_check);
......@@ -922,24 +927,31 @@ Node* InterpreterAssembler::Advance(int delta) {
return Advance(IntPtrConstant(delta));
}
Node* InterpreterAssembler::Advance(Node* delta) {
Node* InterpreterAssembler::Advance(Node* delta, bool backward) {
if (FLAG_trace_ignition) {
TraceBytecode(Runtime::kInterpreterTraceBytecodeExit);
}
Node* next_offset = IntPtrAdd(BytecodeOffset(), delta);
Node* next_offset = backward ? IntPtrSub(BytecodeOffset(), delta)
: IntPtrAdd(BytecodeOffset(), delta);
bytecode_offset_.Bind(next_offset);
return next_offset;
}
Node* InterpreterAssembler::Jump(Node* delta) {
Node* InterpreterAssembler::Jump(Node* delta, bool backward) {
DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_));
UpdateInterruptBudget(TruncateWordToWord32(delta));
Node* new_bytecode_offset = Advance(delta);
UpdateInterruptBudget(TruncateWordToWord32(delta), backward);
Node* new_bytecode_offset = Advance(delta, backward);
Node* target_bytecode = LoadBytecode(new_bytecode_offset);
return DispatchToBytecode(target_bytecode, new_bytecode_offset);
}
Node* InterpreterAssembler::Jump(Node* delta) { return Jump(delta, false); }
Node* InterpreterAssembler::JumpBackward(Node* delta) {
return Jump(delta, true);
}
void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) {
Label match(this), no_match(this);
......@@ -1175,7 +1187,7 @@ void InterpreterAssembler::UpdateInterruptBudgetOnReturn() {
Node* profiling_weight =
Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize),
TruncateWordToWord32(BytecodeOffset()));
UpdateInterruptBudget(profiling_weight);
UpdateInterruptBudget(profiling_weight, false);
}
Node* InterpreterAssembler::StackCheckTriggeredInterrupt() {
......
......@@ -39,6 +39,9 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// Returns the 32-bit unsigned immediate for bytecode operand |operand_index|
// in the current bytecode.
compiler::Node* BytecodeOperandUImm(int operand_index);
// Returns the word-size unsigned immediate for bytecode operand
// |operand_index| in the current bytecode.
compiler::Node* BytecodeOperandUImmWord(int operand_index);
// Returns the 32-bit signed immediate for bytecode operand |operand_index|
// in the current bytecode.
compiler::Node* BytecodeOperandImm(int operand_index);
......@@ -167,15 +170,18 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
compiler::Node* first_arg,
compiler::Node* arg_count, int return_size = 1);
// Jump relative to the current bytecode by |jump_offset|.
// Jump forward relative to the current bytecode by the |jump_offset|.
compiler::Node* Jump(compiler::Node* jump_offset);
// Jump relative to the current bytecode by |jump_offset| if the
// Jump backward relative to the current bytecode by the |jump_offset|.
compiler::Node* JumpBackward(compiler::Node* jump_offset);
// Jump forward relative to the current bytecode by |jump_offset| if the
// word values |lhs| and |rhs| are equal.
void JumpIfWordEqual(compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* jump_offset);
// Jump relative to the current bytecode by |jump_offset| if the
// Jump forward relative to the current bytecode by |jump_offset| if the
// word values |lhs| and |rhs| are not equal.
void JumpIfWordNotEqual(compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* jump_offset);
......@@ -245,9 +251,10 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// Traces the current bytecode by calling |function_id|.
void TraceBytecode(Runtime::FunctionId function_id);
// Updates the bytecode array's interrupt budget by a 32-bit signed |weight|
// and calls Runtime::kInterrupt if counter reaches zero.
void UpdateInterruptBudget(compiler::Node* weight);
// Updates the bytecode array's interrupt budget by a 32-bit unsigned |weight|
// and calls Runtime::kInterrupt if counter reaches zero. If |backward|, then
// the interrupt budget is decremented, otherwise it is incremented.
void UpdateInterruptBudget(compiler::Node* weight, bool backward);
// Returns the offset of register |index| relative to RegisterFilePointer().
compiler::Node* RegisterFrameOffset(compiler::Node* index);
......@@ -278,7 +285,12 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
compiler::Node* BytecodeUnsignedOperand(int operand_index,
OperandSize operand_size);
// Jump relative to the current bytecode by |jump_offset| if the
// Jump relative to the current bytecode by the |jump_offset|. If |backward|,
// then jump backward (subtract the offset), otherwise jump forward (add the
// offset). Helper function for Jump and JumpBackward.
compiler::Node* Jump(compiler::Node* jump_offset, bool backward);
// Jump forward relative to the current bytecode by |jump_offset| if the
// |condition| is true. Helper function for JumpIfWordEqual and
// JumpIfWordNotEqual.
void JumpConditional(compiler::Node* condition, compiler::Node* jump_offset);
......@@ -290,7 +302,7 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// Updates and returns BytecodeOffset() advanced by delta bytecodes.
// Traces the exit of the current bytecode.
compiler::Node* Advance(int delta);
compiler::Node* Advance(compiler::Node* delta);
compiler::Node* Advance(compiler::Node* delta, bool backward = false);
// Load the bytecode at |bytecode_offset|.
compiler::Node* LoadBytecode(compiler::Node* bytecode_offset);
......
......@@ -2391,7 +2391,7 @@ void Interpreter::DoTestUndefined(InterpreterAssembler* assembler) {
//
// Jump by number of bytes represented by the immediate operand |imm|.
void Interpreter::DoJump(InterpreterAssembler* assembler) {
Node* relative_jump = __ BytecodeOperandImmIntPtr(0);
Node* relative_jump = __ BytecodeOperandUImmWord(0);
__ Jump(relative_jump);
}
......@@ -2410,7 +2410,7 @@ void Interpreter::DoJumpConstant(InterpreterAssembler* assembler) {
// accumulator contains true.
void Interpreter::DoJumpIfTrue(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator();
Node* relative_jump = __ BytecodeOperandImmIntPtr(0);
Node* relative_jump = __ BytecodeOperandUImmWord(0);
Node* true_value = __ BooleanConstant(true);
__ JumpIfWordEqual(accumulator, true_value, relative_jump);
}
......@@ -2433,7 +2433,7 @@ void Interpreter::DoJumpIfTrueConstant(InterpreterAssembler* assembler) {
// accumulator contains false.
void Interpreter::DoJumpIfFalse(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator();
Node* relative_jump = __ BytecodeOperandImmIntPtr(0);
Node* relative_jump = __ BytecodeOperandUImmWord(0);
Node* false_value = __ BooleanConstant(false);
__ JumpIfWordEqual(accumulator, false_value, relative_jump);
}
......@@ -2456,7 +2456,7 @@ void Interpreter::DoJumpIfFalseConstant(InterpreterAssembler* assembler) {
// referenced by the accumulator is true when the object is cast to boolean.
void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) {
Node* value = __ GetAccumulator();
Node* relative_jump = __ BytecodeOperandImmIntPtr(0);
Node* relative_jump = __ BytecodeOperandUImmWord(0);
Label if_true(assembler), if_false(assembler);
__ BranchIfToBooleanIsTrue(value, &if_true, &if_false);
__ Bind(&if_true);
......@@ -2489,7 +2489,7 @@ void Interpreter::DoJumpIfToBooleanTrueConstant(
// referenced by the accumulator is false when the object is cast to boolean.
void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) {
Node* value = __ GetAccumulator();
Node* relative_jump = __ BytecodeOperandImmIntPtr(0);
Node* relative_jump = __ BytecodeOperandUImmWord(0);
Label if_true(assembler), if_false(assembler);
__ BranchIfToBooleanIsTrue(value, &if_true, &if_false);
__ Bind(&if_true);
......@@ -2523,7 +2523,7 @@ void Interpreter::DoJumpIfToBooleanFalseConstant(
void Interpreter::DoJumpIfNull(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator();
Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
Node* relative_jump = __ BytecodeOperandImmIntPtr(0);
Node* relative_jump = __ BytecodeOperandUImmWord(0);
__ JumpIfWordEqual(accumulator, null_value, relative_jump);
}
......@@ -2547,7 +2547,7 @@ void Interpreter::DoJumpIfUndefined(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator();
Node* undefined_value =
__ HeapConstant(isolate_->factory()->undefined_value());
Node* relative_jump = __ BytecodeOperandImmIntPtr(0);
Node* relative_jump = __ BytecodeOperandUImmWord(0);
__ JumpIfWordEqual(accumulator, undefined_value, relative_jump);
}
......@@ -2570,7 +2570,7 @@ void Interpreter::DoJumpIfUndefinedConstant(InterpreterAssembler* assembler) {
// referenced by the accumulator is a JSReceiver.
void Interpreter::DoJumpIfJSReceiver(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator();
Node* relative_jump = __ BytecodeOperandImmIntPtr(0);
Node* relative_jump = __ BytecodeOperandUImmWord(0);
Label if_object(assembler), if_notobject(assembler, Label::kDeferred),
if_notsmi(assembler);
......@@ -2614,7 +2614,7 @@ void Interpreter::DoJumpIfJSReceiverConstant(InterpreterAssembler* assembler) {
void Interpreter::DoJumpIfNotHole(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator();
Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
Node* relative_jump = __ BytecodeOperandImmIntPtr(0);
Node* relative_jump = __ BytecodeOperandUImmWord(0);
__ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump);
}
......@@ -2636,7 +2636,7 @@ void Interpreter::DoJumpIfNotHoleConstant(InterpreterAssembler* assembler) {
// performs a loop nesting check and potentially triggers OSR in case the
// current OSR level matches (or exceeds) the specified |loop_depth|.
void Interpreter::DoJumpLoop(InterpreterAssembler* assembler) {
Node* relative_jump = __ BytecodeOperandImmIntPtr(0);
Node* relative_jump = __ BytecodeOperandUImmWord(0);
Node* loop_depth = __ BytecodeOperandImm(1);
Node* osr_level = __ LoadOSRNestingLevel();
......@@ -2647,7 +2647,7 @@ void Interpreter::DoJumpLoop(InterpreterAssembler* assembler) {
__ Branch(condition, &ok, &osr_armed);
__ Bind(&ok);
__ Jump(relative_jump);
__ JumpBackward(relative_jump);
__ Bind(&osr_armed);
{
......@@ -2655,7 +2655,7 @@ void Interpreter::DoJumpLoop(InterpreterAssembler* assembler) {
Node* target = __ HeapConstant(callable.code());
Node* context = __ GetContext();
__ CallStub(callable.descriptor(), target, context);
__ Jump(relative_jump);
__ JumpBackward(relative_jump);
}
}
......
......@@ -88,7 +88,7 @@ bytecodes: [
/* 132 E> */ B(TestEqual), R(0), U8(6),
B(JumpIfFalse), U8(4),
/* 138 S> */ B(Jump), U8(5),
B(JumpLoop), U8(-40), U8(0),
B(JumpLoop), U8(40), U8(0),
/* 147 S> */ B(Ldar), R(1),
/* 157 S> */ B(Return),
]
......@@ -141,7 +141,7 @@ bytecodes: [
/* 173 S> */ B(LdaSmi), U8(1),
/* 179 E> */ B(Add), R(0), U8(7),
B(Star), R(0),
B(JumpLoop), U8(-52), U8(0),
B(JumpLoop), U8(52), U8(0),
/* 186 S> */ B(Ldar), R(0),
/* 196 S> */ B(Return),
]
......@@ -182,7 +182,7 @@ bytecodes: [
/* 105 S> */ B(LdaSmi), U8(1),
/* 111 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
B(JumpLoop), U8(-24), U8(1),
B(JumpLoop), U8(24), U8(1),
/* 122 S> */ B(LdaSmi), U8(1),
/* 128 E> */ B(Add), R(0), U8(5),
B(Star), R(0),
......@@ -223,7 +223,7 @@ bytecodes: [
/* 85 S> */ B(LdaSmi), U8(1),
/* 91 E> */ B(Sub), R(0), U8(3),
B(Star), R(0),
B(JumpLoop), U8(-19), U8(0),
B(JumpLoop), U8(19), U8(0),
/* 98 S> */ B(Ldar), R(1),
/* 108 S> */ B(Return),
]
......@@ -270,7 +270,7 @@ bytecodes: [
/* 144 S> */ B(LdaSmi), U8(10),
/* 144 E> */ B(TestLessThan), R(0), U8(6),
B(JumpIfFalse), U8(5),
B(JumpLoop), U8(-40), U8(0),
B(JumpLoop), U8(40), U8(0),
/* 151 S> */ B(Ldar), R(1),
/* 161 S> */ B(Return),
]
......@@ -306,7 +306,7 @@ bytecodes: [
/* 84 E> */ B(Sub), R(0), U8(3),
B(Star), R(0),
/* 98 S> */ B(JumpIfToBooleanFalse), U8(5),
B(JumpLoop), U8(-17), U8(0),
B(JumpLoop), U8(17), U8(0),
/* 102 S> */ B(Ldar), R(1),
/* 112 S> */ B(Return),
]
......@@ -393,7 +393,7 @@ bytecodes: [
/* 117 E> */ B(TestEqual), R(0), U8(5),
B(JumpIfFalse), U8(4),
/* 123 S> */ B(Jump), U8(2),
B(JumpLoop), U8(-33), U8(0),
B(JumpLoop), U8(33), U8(0),
/* 149 S> */ B(Ldar), R(1),
/* 159 S> */ B(Return),
]
......@@ -430,7 +430,7 @@ bytecodes: [
/* 103 S> */ B(LdaSmi), U8(1),
/* 109 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
B(JumpLoop), U8(-26), U8(0),
B(JumpLoop), U8(26), U8(0),
B(LdaUndefined),
/* 116 S> */ B(Return),
]
......@@ -466,7 +466,7 @@ bytecodes: [
/* 101 S> */ B(LdaSmi), U8(1),
/* 107 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
B(JumpLoop), U8(-26), U8(0),
B(JumpLoop), U8(26), U8(0),
B(LdaUndefined),
/* 114 S> */ B(Return),
]
......@@ -502,7 +502,7 @@ bytecodes: [
/* 55 S> */ B(LdaSmi), U8(1),
/* 59 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
B(JumpLoop), U8(-26), U8(0),
B(JumpLoop), U8(26), U8(0),
B(LdaUndefined),
/* 113 S> */ B(Return),
]
......@@ -537,7 +537,7 @@ bytecodes: [
/* 53 S> */ B(LdaSmi), U8(1),
/* 57 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
B(JumpLoop), U8(-26), U8(0),
B(JumpLoop), U8(26), U8(0),
B(LdaUndefined),
/* 111 S> */ B(Return),
]
......@@ -574,7 +574,7 @@ bytecodes: [
/* 72 S> */ B(LdaSmi), U8(1),
/* 76 E> */ B(Add), R(1), U8(3),
B(Star), R(1),
B(JumpLoop), U8(-24), U8(0),
B(JumpLoop), U8(24), U8(0),
B(LdaUndefined),
/* 110 S> */ B(Return),
]
......@@ -609,7 +609,7 @@ bytecodes: [
/* 67 S> */ B(Ldar), R(1),
B(Dec), U8(2),
B(Star), R(1),
B(JumpLoop), U8(-18), U8(0),
B(JumpLoop), U8(18), U8(0),
/* 88 S> */ B(Ldar), R(0),
/* 98 S> */ B(Return),
]
......@@ -672,7 +672,7 @@ bytecodes: [
/* 69 S> */ B(Ldar), R(1),
B(Inc), U8(2),
B(Star), R(1),
B(JumpLoop), U8(-23), U8(0),
B(JumpLoop), U8(23), U8(0),
/* 112 S> */ B(Ldar), R(0),
/* 122 S> */ B(Return),
]
......@@ -722,7 +722,7 @@ bytecodes: [
B(Inc), U8(3),
/* 127 E> */ B(StaCurrentContextSlot), U8(4),
B(PopContext), R(3),
B(JumpLoop), U8(-45), U8(0),
B(JumpLoop), U8(45), U8(0),
B(LdaUndefined),
/* 137 S> */ B(Return),
]
......
......@@ -79,11 +79,11 @@ bytecodes: [
/* 118 S> */ B(Ldar), R(2),
B(Inc), U8(5),
B(Star), R(2),
B(JumpLoop), U8(-36), U8(1),
B(JumpLoop), U8(36), U8(1),
/* 84 S> */ B(Ldar), R(1),
B(Inc), U8(3),
B(Star), R(1),
B(JumpLoop), U8(-56), U8(0),
B(JumpLoop), U8(56), U8(0),
/* 188 S> */ B(Ldar), R(0),
/* 200 S> */ B(Return),
]
......
......@@ -85,7 +85,7 @@ bytecodes: [
/* 85 S> */ B(Return),
B(ForInStep), R(7),
B(Star), R(7),
B(JumpLoop), U8(-23), U8(0),
B(JumpLoop), U8(23), U8(0),
B(LdaUndefined),
/* 85 S> */ B(Return),
]
......@@ -127,7 +127,7 @@ bytecodes: [
B(Star), R(0),
/* 72 E> */ B(ForInStep), R(7),
B(Star), R(7),
B(JumpLoop), U8(-31), U8(0),
B(JumpLoop), U8(31), U8(0),
B(LdaUndefined),
/* 80 S> */ B(Return),
]
......@@ -182,7 +182,7 @@ bytecodes: [
/* 143 S> */ B(Jump), U8(9),
B(ForInStep), R(5),
B(Star), R(5),
B(JumpLoop), U8(-55), U8(0),
B(JumpLoop), U8(55), U8(0),
B(LdaUndefined),
/* 152 S> */ B(Return),
]
......@@ -228,7 +228,7 @@ bytecodes: [
/* 98 S> */ B(Return),
B(ForInStep), R(5),
B(Star), R(5),
B(JumpLoop), U8(-34), U8(0),
B(JumpLoop), U8(34), U8(0),
B(LdaUndefined),
/* 98 S> */ B(Return),
]
......
......@@ -45,7 +45,7 @@ bytecodes: [
B(Mov), R(0), R(1),
B(LdaZero),
B(Star), R(4),
B(JumpLoop), U8(-51), U8(0),
B(JumpLoop), U8(51), U8(0),
B(Jump), U8(36),
B(Star), R(13),
B(Ldar), R(closure),
......@@ -348,7 +348,7 @@ bytecodes: [
/* 104 S> */ B(Jump), U8(8),
B(LdaZero),
B(Star), R(4),
B(JumpLoop), U8(-69), U8(0),
B(JumpLoop), U8(69), U8(0),
B(Jump), U8(36),
B(Star), R(13),
B(Ldar), R(closure),
......
......@@ -138,7 +138,7 @@ bytecodes: [
B(JumpIfTrue), U8(60),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrueConstant), U8(0),
B(JumpIfTrue), U8(130),
B(LdaSmi), U8(78),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
......@@ -268,7 +268,6 @@ bytecodes: [
/* 25 S> */ B(Return),
]
constant pool: [
Smi [130],
]
handlers: [
[53, 228, 234],
......@@ -281,7 +280,7 @@ snippet: "
"
frame size: 18
parameter count: 1
bytecode array length: 778
bytecode array length: 775
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(35),
......@@ -294,7 +293,7 @@ bytecodes: [
B(JumpIfTrue), U8(60),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrueConstant), U8(3),
B(JumpIfTrue), U8(154),
B(LdaSmi), U8(78),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
......@@ -338,7 +337,7 @@ bytecodes: [
B(Star), R(6),
B(LdaZero),
B(Star), R(5),
B(JumpConstant), U8(18),
B(JumpConstant), U8(13),
B(Ldar), R(10),
/* 11 E> */ B(Throw),
B(Ldar), R(closure),
......@@ -363,13 +362,13 @@ bytecodes: [
B(JumpIfTrue), U8(18),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrueConstant), U8(8),
B(JumpIfTrue), U8(134),
B(LdaSmi), U8(78),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kAbort), R(12), U8(1),
/* 27 S> */ B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(4), U8(8),
B(LdaNamedProperty), R(13), U8(3), U8(8),
B(Star), R(12),
/* 27 E> */ B(CallProperty), R(12), R(13), U8(1), U8(6),
/* 27 E> */ B(StaContextSlot), R(1), U8(8), U8(0),
......@@ -382,11 +381,11 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(5), U8(10),
B(JumpIfToBooleanTrueConstant), U8(9),
B(LdaNamedProperty), R(12), U8(4), U8(10),
B(JumpIfToBooleanTrue), U8(147),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(6), U8(12),
B(LdaNamedProperty), R(12), U8(5), U8(12),
B(StaContextSlot), R(1), U8(10), U8(0),
B(LdaSmi), U8(2),
B(StaContextSlot), R(1), U8(9), U8(0),
......@@ -394,7 +393,7 @@ bytecodes: [
B(StaContextSlot), R(1), U8(6), U8(0),
/* 16 E> */ B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(7),
B(CreateBlockContext), U8(6),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
......@@ -438,17 +437,17 @@ bytecodes: [
B(Star), R(9),
B(LdaZero),
B(Star), R(8),
B(Jump), U8(74),
B(Jump), U8(71),
B(Ldar), R(14),
/* 36 E> */ B(Throw),
B(PopContext), R(2),
B(LdaZero),
B(StaContextSlot), R(1), U8(9), U8(0),
B(Wide), B(JumpLoop), U16(-219), U16(0),
B(JumpLoop), U8(218), U8(0),
B(Jump), U8(44),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(10), U8(11),
B(CreateCatchContext), R(12), U8(7), U8(8),
B(Star), R(11),
B(PushContext), R(2),
B(LdaContextSlot), R(1), U8(9), U8(0),
......@@ -475,16 +474,16 @@ bytecodes: [
B(Star), R(11),
B(LdaZero),
B(TestEqualStrict), R(11), U8(15),
B(JumpIfTrueConstant), U8(17),
B(JumpIfTrue), U8(159),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(11),
B(LdaNamedProperty), R(11), U8(12), U8(16),
B(LdaNamedProperty), R(11), U8(9), U8(16),
B(StaContextSlot), R(1), U8(11), U8(0),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(Star), R(11),
B(TestUndetectable), R(11),
B(JumpIfFalse), U8(4),
B(JumpConstant), U8(16),
B(Jump), U8(133),
B(LdaContextSlot), R(1), U8(9), U8(0),
B(Star), R(11),
B(LdaSmi), U8(1),
......@@ -493,13 +492,13 @@ bytecodes: [
B(LdaContextSlot), R(1), U8(11), U8(0),
B(TypeOf),
B(Star), R(11),
B(LdaConstant), U8(13),
B(LdaConstant), U8(10),
B(TestEqualStrict), R(11), U8(20),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(11),
B(LdaConstant), U8(14),
B(LdaConstant), U8(11),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(Throw),
......@@ -512,7 +511,7 @@ bytecodes: [
B(Jump), U8(20),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(10), U8(15),
B(CreateCatchContext), R(12), U8(7), U8(12),
B(Star), R(11),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -612,27 +611,22 @@ constant pool: [
FIXED_ARRAY_TYPE,
CONSTANT_ELEMENTS_PAIR_TYPE,
SYMBOL_TYPE,
Smi [154],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
FIXED_ARRAY_TYPE,
Smi [134],
Smi [150],
ONE_BYTE_INTERNALIZED_STRING_TYPE [".catch"],
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["function"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
FIXED_ARRAY_TYPE,
Smi [133],
Smi [159],
Smi [582],
Smi [579],
]
handlers: [
[53, 697, 703],
[149, 448, 454],
[152, 404, 406],
[550, 566, 568],
[53, 694, 700],
[149, 445, 451],
[152, 401, 403],
[547, 563, 565],
]
......@@ -971,7 +971,7 @@ bytecodes: [
/* 4114 S> */ B(Ldar), R(1),
B(Inc), U8(3),
B(Star), R(1),
B(JumpLoop), U8(-42), U8(0),
B(JumpLoop), U8(42), U8(0),
/* 4167 S> */ B(LdaSmi), U8(3),
/* 4177 S> */ B(Return),
]
......
......@@ -29,7 +29,7 @@ bytecodes: [
/* 95 E> */ B(TestGreaterThan), R(0), U8(3),
B(JumpIfFalse), U8(4),
/* 101 S> */ B(Jump), U8(5),
B(JumpLoop), U8(-17), U8(0),
B(JumpLoop), U8(17), U8(0),
/* 110 S> */ B(Ldar), R(0),
/* 123 S> */ B(Return),
]
......
......@@ -27,7 +27,7 @@ bytecodes: [
/* 65 S> */ B(LdaSmi), U8(10),
/* 71 E> */ B(Add), R(0), U8(3),
B(Star), R(0),
B(JumpLoop), U8(-15), U8(0),
B(JumpLoop), U8(15), U8(0),
/* 79 S> */ B(Ldar), R(0),
/* 89 S> */ B(Return),
]
......@@ -58,7 +58,7 @@ bytecodes: [
/* 74 S> */ B(LdaFalse),
/* 74 E> */ B(TestEqual), R(0), U8(2),
B(JumpIfFalse), U8(5),
B(JumpLoop), U8(-12), U8(0),
B(JumpLoop), U8(12), U8(0),
/* 85 S> */ B(Ldar), R(0),
/* 95 S> */ B(Return),
]
......
......@@ -911,7 +911,7 @@ bytecodes: [
/* 1548 S> */ B(Wide), B(Ldar), R16(128),
B(Inc), U8(3),
B(Wide), B(Star), R16(128),
B(JumpLoop), U8(-36), U8(0),
B(JumpLoop), U8(36), U8(0),
/* 1567 S> */ B(Wide), B(Ldar), R16(128),
/* 1580 S> */ B(Return),
]
......@@ -1111,7 +1111,7 @@ bytecodes: [
B(Star), R(1),
/* 1544 E> */ B(Wide), B(ForInStep), R16(161),
B(Wide), B(Star), R16(161),
B(JumpLoop), U8(-48), U8(0),
B(JumpLoop), U8(48), U8(0),
/* 1553 S> */ B(Ldar), R(1),
/* 1564 S> */ B(Return),
]
......
......@@ -365,8 +365,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
builder.Debugger();
// Insert dummy ops to force longer jumps.
for (int i = 0; i < 128; i++) {
builder.LoadTrue();
for (int i = 0; i < 256; i++) {
builder.Debugger();
}
// Bind labels for long jumps at the very end.
......@@ -524,7 +524,7 @@ static Bytecode PeepholeToBoolean(Bytecode jump_bytecode) {
TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
CanonicalHandleScope canonical(isolate());
static const int kFarJumpDistance = 256;
static const int kFarJumpDistance = 256 + 20;
BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1);
......@@ -569,7 +569,7 @@ TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
BytecodeArrayIterator iterator(array);
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
CHECK_EQ(iterator.GetImmediateOperand(0), 22);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 22);
iterator.Advance();
// Ignore compare operation.
......@@ -577,7 +577,7 @@ TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
CHECK_EQ(iterator.current_bytecode(),
PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue));
CHECK_EQ(iterator.GetImmediateOperand(0), 17);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 17);
iterator.Advance();
// Ignore compare operation.
......@@ -585,21 +585,21 @@ TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
CHECK_EQ(iterator.current_bytecode(),
PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse));
CHECK_EQ(iterator.GetImmediateOperand(0), 12);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 12);
iterator.Advance();
// Ignore add operation.
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue);
CHECK_EQ(iterator.GetImmediateOperand(0), 7);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 7);
iterator.Advance();
// Ignore add operation.
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
CHECK_EQ(iterator.GetImmediateOperand(0), 2);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 2);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
......@@ -670,13 +670,13 @@ TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate());
BytecodeArrayIterator iterator(array);
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop);
CHECK_EQ(iterator.GetImmediateOperand(0), 0);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 0);
iterator.Advance();
for (int i = 0; i < 42; i++) {
for (unsigned i = 0; i < 42; i++) {
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop);
CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
// offset of 3 (because kJumpLoop takes two immediate operands)
CHECK_EQ(iterator.GetImmediateOperand(0), -i * 3 - 3);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), i * 3 + 3);
iterator.Advance();
}
// Check padding to force wide backwards jumps.
......@@ -686,7 +686,7 @@ TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
}
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop);
CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble);
CHECK_EQ(iterator.GetImmediateOperand(0), -386);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 386);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
iterator.Advance();
......@@ -713,13 +713,13 @@ TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate());
BytecodeArrayIterator iterator(array);
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
CHECK_EQ(iterator.GetImmediateOperand(0), 2);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 2);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop);
CHECK_EQ(iterator.GetImmediateOperand(0), 0);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 0);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop);
CHECK_EQ(iterator.GetImmediateOperand(0), -3);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 3);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
iterator.Advance();
......@@ -747,13 +747,13 @@ TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) {
BytecodeArrayIterator iterator(array);
for (int i = 0; i < kRepeats; i++) {
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
CHECK_EQ(iterator.GetImmediateOperand(0), 2);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 2);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop);
CHECK_EQ(iterator.GetImmediateOperand(0), 0);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 0);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop);
CHECK_EQ(iterator.GetImmediateOperand(0), -3);
CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 3);
iterator.Advance();
}
CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
......
......@@ -168,7 +168,7 @@ TEST_F(BytecodeArrayWriterUnittest, ComplexExample) {
/* 36 85 S> */ B(Return),
/* 37 */ B(ForInStep), R8(7),
/* 39 */ B(Star), R8(7),
/* 41 */ B(JumpLoop), U8(-24), U8(0),
/* 41 */ B(JumpLoop), U8(24), U8(0),
/* 44 */ B(LdaUndefined),
/* 45 85 S> */ B(Return),
// clang-format on
......
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