Commit c9864173 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[interpreter] Merge {OsrPoll} with {Jump} bytecode.

This introduces a new {JumpLoop} bytecode to combine the OSR polling
mechanism modeled by {OsrPoll} with the actual {Jump} performing the
backwards branch. This reduces the overall size and also avoids one
additional dispatch. It also makes sure that OSR polling is only done
within real loops.

R=rmcilroy@chromium.org
BUG=v8:4764

Review-Url: https://codereview.chromium.org/2331033002
Cr-Commit-Position: refs/heads/master@{#39384}
parent 26f3e304
......@@ -1616,14 +1616,14 @@ void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
BuildJumpIfEqual(jsgraph()->UndefinedConstant());
}
void BytecodeGraphBuilder::VisitJumpLoop() { BuildJump(); }
void BytecodeGraphBuilder::VisitStackCheck() {
FrameStateBeforeAndAfter states(this);
Node* node = NewNode(javascript()->StackCheck());
environment()->RecordAfterState(node, &states);
}
void BytecodeGraphBuilder::VisitOsrPoll() {}
void BytecodeGraphBuilder::VisitReturn() {
BuildLoopExitsForFunctionExit();
Node* control =
......
......@@ -452,43 +452,54 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(BytecodeNode* node,
BytecodeLabel* label) {
BytecodeNode node(jump_bytecode, 0);
AttachSourceInfo(&node);
pipeline_->WriteJump(&node, label);
AttachSourceInfo(node);
pipeline_->WriteJump(node, label);
LeaveBasicBlock();
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
return OutputJump(Bytecode::kJump, label);
BytecodeNode node(Bytecode::kJump, 0);
return OutputJump(&node, label);
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) {
// The peephole optimizer attempts to simplify JumpIfToBooleanTrue
// to JumpIfTrue.
return OutputJump(Bytecode::kJumpIfToBooleanTrue, label);
BytecodeNode node(Bytecode::kJumpIfToBooleanTrue, 0);
return OutputJump(&node, label);
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) {
// The peephole optimizer attempts to simplify JumpIfToBooleanFalse
// to JumpIfFalse.
return OutputJump(Bytecode::kJumpIfToBooleanFalse, label);
BytecodeNode node(Bytecode::kJumpIfToBooleanFalse, 0);
return OutputJump(&node, label);
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) {
return OutputJump(Bytecode::kJumpIfNull, label);
BytecodeNode node(Bytecode::kJumpIfNull, 0);
return OutputJump(&node, label);
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined(
BytecodeLabel* label) {
return OutputJump(Bytecode::kJumpIfUndefined, label);
BytecodeNode node(Bytecode::kJumpIfUndefined, 0);
return OutputJump(&node, label);
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
BytecodeLabel* label) {
return OutputJump(Bytecode::kJumpIfNotHole, label);
BytecodeNode node(Bytecode::kJumpIfNotHole, 0);
return OutputJump(&node, label);
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label,
int loop_depth) {
BytecodeNode node(Bytecode::kJumpLoop, 0, UnsignedOperand(loop_depth));
return OutputJump(&node, label);
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
......@@ -509,11 +520,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::OsrPoll(int loop_depth) {
Output(Bytecode::kOsrPoll, UnsignedOperand(loop_depth));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() {
Output(Bytecode::kThrow);
return *this;
......
......@@ -254,11 +254,10 @@ class BytecodeArrayBuilder final : public ZoneObject {
BytecodeArrayBuilder& JumpIfNotHole(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfUndefined(BytecodeLabel* label);
BytecodeArrayBuilder& JumpLoop(BytecodeLabel* label, int loop_depth);
BytecodeArrayBuilder& StackCheck(int position);
BytecodeArrayBuilder& OsrPoll(int loop_depth);
BytecodeArrayBuilder& Throw();
BytecodeArrayBuilder& ReThrow();
BytecodeArrayBuilder& Return();
......@@ -352,8 +351,7 @@ class BytecodeArrayBuilder final : public ZoneObject {
void Output(Bytecode bytecode, uint32_t operand0);
void Output(Bytecode bytecode);
BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode,
BytecodeLabel* label);
BytecodeArrayBuilder& OutputJump(BytecodeNode* node, BytecodeLabel* label);
bool RegisterIsValid(Register reg) const;
bool OperandsAreValid(Bytecode bytecode, int operand_count,
......
......@@ -357,7 +357,8 @@ void BytecodeArrayWriter::EmitJump(BytecodeNode* node, BytecodeLabel* label) {
DCHECK_LE(delta, 0);
delta -= 1;
}
node->set_bytecode(node->bytecode(), delta);
DCHECK_EQ(Bytecode::kJumpLoop, node->bytecode());
node->set_bytecode(node->bytecode(), delta, node->operand(1));
} else {
// The label has not yet been bound so this is a forward reference
// that will be patched when the label is bound. We create a
......@@ -369,6 +370,7 @@ void BytecodeArrayWriter::EmitJump(BytecodeNode* node, BytecodeLabel* label) {
label->set_referrer(current_offset);
OperandSize reserved_operand_size =
constant_array_builder()->CreateReservedEntry();
DCHECK_NE(Bytecode::kJumpLoop, node->bytecode());
switch (reserved_operand_size) {
case OperandSize::kNone:
UNREACHABLE();
......
......@@ -826,14 +826,6 @@ void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt,
loop_builder->LoopHeader(&resume_points_in_loop);
// Insert an explicit {OsrPoll} right after the loop header, to trigger
// on-stack replacement when armed for the given loop nesting depth.
if (FLAG_ignition_osr) {
// TODO(4764): Merge this with another bytecode (e.g. {Jump} back edge).
int level = Min(loop_depth_, AbstractCode::kMaxLoopNestingMarker - 1);
builder()->OsrPoll(level);
}
if (stmt->yield_count() > 0) {
// If we are not resuming, fall through to loop body.
// If we are resuming, perform state dispatch.
......@@ -1170,13 +1162,16 @@ void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
} else if (stmt->cond()->ToBooleanIsTrue()) {
VisitIterationHeader(stmt, &loop_builder);
VisitIterationBody(stmt, &loop_builder);
loop_builder.JumpToHeader();
loop_builder.JumpToHeader(loop_depth_);
} else {
VisitIterationHeader(stmt, &loop_builder);
VisitIterationBody(stmt, &loop_builder);
builder()->SetExpressionAsStatementPosition(stmt->cond());
VisitForTest(stmt->cond(), loop_builder.header_labels(),
loop_builder.break_labels(), TestFallthrough::kElse);
BytecodeLabels loop_backbranch(zone());
VisitForTest(stmt->cond(), &loop_backbranch, loop_builder.break_labels(),
TestFallthrough::kThen);
loop_backbranch.Bind(builder());
loop_builder.JumpToHeader(loop_depth_);
}
loop_builder.EndLoop();
}
......@@ -1197,7 +1192,7 @@ void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
loop_body.Bind(builder());
}
VisitIterationBody(stmt, &loop_builder);
loop_builder.JumpToHeader();
loop_builder.JumpToHeader(loop_depth_);
loop_builder.EndLoop();
}
......@@ -1225,7 +1220,7 @@ void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
builder()->SetStatementPosition(stmt->next());
Visit(stmt->next());
}
loop_builder.JumpToHeader();
loop_builder.JumpToHeader(loop_depth_);
loop_builder.EndLoop();
}
......@@ -1346,7 +1341,7 @@ void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
VisitIterationBody(stmt, &loop_builder);
builder()->ForInStep(index);
builder()->StoreAccumulatorInRegister(index);
loop_builder.JumpToHeader();
loop_builder.JumpToHeader(loop_depth_);
loop_builder.EndLoop();
builder()->Bind(&subject_null_label);
builder()->Bind(&subject_undefined_label);
......@@ -1366,7 +1361,7 @@ void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
VisitForEffect(stmt->assign_each());
VisitIterationBody(stmt, &loop_builder);
loop_builder.JumpToHeader();
loop_builder.JumpToHeader(loop_depth_);
loop_builder.EndLoop();
}
......
......@@ -407,7 +407,8 @@ bool Bytecodes::IsConditionalJump(Bytecode bytecode) {
// static
bool Bytecodes::IsJumpImmediate(Bytecode bytecode) {
return bytecode == Bytecode::kJump || IsConditionalJumpImmediate(bytecode);
return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop ||
IsConditionalJumpImmediate(bytecode);
}
......
......@@ -273,6 +273,7 @@ namespace interpreter {
V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \
V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm) \
V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \
V(JumpLoop, AccumulatorUse::kNone, OperandType::kImm, OperandType::kImm) \
\
/* Complex flow control For..in */ \
V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg, \
......@@ -286,9 +287,6 @@ namespace interpreter {
/* Perform a stack guard check */ \
V(StackCheck, AccumulatorUse::kNone) \
\
/* Perform a check to trigger on-stack replacement */ \
V(OsrPoll, AccumulatorUse::kNone, OperandType::kImm) \
\
/* Non-local flow control */ \
V(Throw, AccumulatorUse::kRead) \
V(ReThrow, AccumulatorUse::kRead) \
......
......@@ -60,18 +60,14 @@ void LoopBuilder::LoopHeader(ZoneVector<BytecodeLabel>* additional_labels) {
}
}
void LoopBuilder::JumpToHeader() {
void LoopBuilder::JumpToHeader(int loop_depth) {
// Pass the proper loop nesting level to the backwards branch, to trigger
// on-stack replacement when armed for the given loop nesting depth.
int level = Min(loop_depth, AbstractCode::kMaxLoopNestingMarker - 1);
// Loop must have closed form, i.e. all loop elements are within the loop,
// the loop header precedes the body and next elements in the loop.
DCHECK(loop_header_.is_bound());
builder()->Jump(&loop_header_);
}
void LoopBuilder::JumpToHeaderIfTrue() {
// Loop must have closed form, i.e. all loop elements are within the loop,
// the loop header precedes the body and next elements in the loop.
DCHECK(loop_header_.is_bound());
builder()->JumpIfTrue(&loop_header_);
builder()->JumpLoop(&loop_header_, level);
}
void LoopBuilder::EndLoop() {
......
......@@ -86,8 +86,7 @@ class LoopBuilder final : public BreakableControlFlowBuilder {
~LoopBuilder();
void LoopHeader(ZoneVector<BytecodeLabel>* additional_labels);
void JumpToHeader();
void JumpToHeaderIfTrue();
void JumpToHeader(int loop_depth);
void BindContinueTarget();
void EndLoop();
......@@ -99,9 +98,6 @@ class LoopBuilder final : public BreakableControlFlowBuilder {
void ContinueIfUndefined() { EmitJumpIfUndefined(&continue_labels_); }
void ContinueIfNull() { EmitJumpIfNull(&continue_labels_); }
BytecodeLabels* header_labels() { return &header_labels_; }
BytecodeLabels* continue_labels() { return &continue_labels_; }
private:
BytecodeLabel loop_header_;
......
......@@ -938,6 +938,9 @@ Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context,
}
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.
Label ok(this), interrupt_check(this, Label::kDeferred), end(this);
Node* budget_offset =
IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag);
......
......@@ -1854,6 +1854,35 @@ void Interpreter::DoJumpIfNotHoleConstant(InterpreterAssembler* assembler) {
__ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump);
}
// JumpLoop <imm> <loop_depth>
//
// Jump by number of bytes represented by the immediate operand |imm|. Also
// 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 = __ BytecodeOperandImm(0);
Node* loop_depth = __ BytecodeOperandImm(1);
Node* osr_level = __ LoadOSRNestingLevel();
// Check if OSR points at the given {loop_depth} are armed by comparing it to
// the current {osr_level} loaded from the header of the BytecodeArray.
Label ok(assembler), osr_armed(assembler, Label::kDeferred);
Node* condition = __ Int32GreaterThanOrEqual(loop_depth, osr_level);
__ Branch(condition, &ok, &osr_armed);
__ Bind(&ok);
__ Jump(relative_jump);
__ Bind(&osr_armed);
{
Callable callable = CodeFactory::InterpreterOnStackReplacement(isolate_);
Node* target = __ HeapConstant(callable.code());
Node* context = __ GetContext();
__ CallStub(callable.descriptor(), target, context);
__ Jump(relative_jump);
}
}
// CreateRegExpLiteral <pattern_idx> <literal_idx> <flags>
//
// Creates a regular expression literal for literal index <literal_idx> with
......@@ -2124,32 +2153,6 @@ void Interpreter::DoStackCheck(InterpreterAssembler* assembler) {
}
}
// OsrPoll <loop_depth>
//
// Performs a loop nesting check and potentially triggers OSR.
void Interpreter::DoOsrPoll(InterpreterAssembler* assembler) {
Node* loop_depth = __ BytecodeOperandImm(0);
Node* osr_level = __ LoadOSRNestingLevel();
// Check if OSR points at the given {loop_depth} are armed by comparing it to
// the current {osr_level} loaded from the header of the BytecodeArray.
Label ok(assembler), osr_armed(assembler, Label::kDeferred);
Node* condition = __ Int32GreaterThanOrEqual(loop_depth, osr_level);
__ Branch(condition, &ok, &osr_armed);
__ Bind(&ok);
__ Dispatch();
__ Bind(&osr_armed);
{
Callable callable = CodeFactory::InterpreterOnStackReplacement(isolate_);
Node* target = __ HeapConstant(callable.code());
Node* context = __ GetContext();
__ CallStub(callable.descriptor(), target, context);
__ Dispatch();
}
}
// Throw
//
// Throws the exception in the accumulator.
......
......@@ -11,6 +11,7 @@
#include "src/deoptimizer.h"
#include "src/frames-inl.h"
#include "src/full-codegen/full-codegen.h"
#include "src/interpreter/bytecode-array-iterator.h"
#include "src/isolate-inl.h"
#include "src/messages.h"
#include "src/v8threads.h"
......@@ -292,7 +293,20 @@ BailoutId DetermineEntryAndDisarmOSRForInterpreter(JavaScriptFrame* frame) {
// Reset the OSR loop nesting depth to disarm back edges.
bytecode->set_osr_loop_nesting_level(0);
return BailoutId(iframe->GetBytecodeOffset());
// Translate the offset of the jump instruction to the jump target offset of
// that instruction so that the derived BailoutId points to the loop header.
// TODO(mstarzinger): This can be merged with {BytecodeBranchAnalysis} which
// already performs a pre-pass over the bytecode stream anyways.
int jump_offset = iframe->GetBytecodeOffset();
interpreter::BytecodeArrayIterator iterator(bytecode);
while (iterator.current_offset() + iterator.current_prefix_offset() <
jump_offset) {
iterator.Advance();
}
DCHECK(interpreter::Bytecodes::IsJump(iterator.current_bytecode()));
int jump_target_offset = iterator.GetJumpTargetOffset();
return BailoutId(jump_target_offset);
}
} // namespace
......
......@@ -49,7 +49,7 @@ snippet: "
"
frame size: 5
parameter count: 1
bytecode array length: 67
bytecode array length: 69
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 44 S> */ B(LdaZero),
......@@ -58,13 +58,13 @@ bytecodes: [
B(Star), R(1),
/* 76 S> */ B(LdaSmi), U8(10),
/* 76 E> */ B(TestLessThan), R(1), U8(1),
B(JumpIfFalse), U8(52),
B(JumpIfFalse), U8(54),
/* 58 E> */ B(StackCheck),
/* 106 S> */ B(LdaZero),
B(Star), R(2),
/* 111 S> */ B(LdaSmi), U8(3),
/* 111 E> */ B(TestLessThan), R(2), U8(3),
B(JumpIfFalse), U8(33),
B(JumpIfFalse), U8(34),
/* 93 E> */ B(StackCheck),
/* 129 S> */ B(Ldar), R(0),
B(Inc), U8(5),
......@@ -75,15 +75,15 @@ bytecodes: [
B(LdaSmi), U8(12),
/* 152 E> */ B(TestEqual), R(4), U8(7),
B(JumpIfFalse), U8(4),
/* 161 S> */ B(Jump), U8(18),
/* 161 S> */ B(Jump), U8(20),
/* 118 S> */ B(Ldar), R(2),
B(Inc), U8(4),
B(Star), R(2),
B(Jump), U8(-36),
B(JumpLoop), U8(-36), U8(1),
/* 84 S> */ B(Ldar), R(1),
B(Inc), U8(2),
B(Star), R(1),
B(Jump), U8(-55),
B(JumpLoop), U8(-56), U8(0),
/* 188 S> */ B(Ldar), R(0),
/* 200 S> */ B(Return),
]
......
......@@ -64,19 +64,19 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 44
bytecode array length: 45
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 68 S> */ B(JumpIfUndefined), U8(37),
B(JumpIfNull), U8(35),
/* 68 S> */ B(JumpIfUndefined), U8(38),
B(JumpIfNull), U8(36),
B(ToObject), R(3),
B(ForInPrepare), R(3), R(4),
B(LdaZero),
B(Star), R(7),
/* 63 S> */ B(ForInContinue), R(7), R(6),
B(JumpIfFalse), U8(22),
B(JumpIfFalse), U8(23),
B(ForInNext), R(3), R(7), R(4), U8(1),
B(JumpIfUndefined), U8(9),
B(Star), R(1),
......@@ -86,7 +86,7 @@ bytecodes: [
/* 85 S> */ B(Return),
B(ForInStep), R(7),
B(Star), R(7),
B(Jump), U8(-23),
B(JumpLoop), U8(-23), U8(0),
B(LdaUndefined),
/* 85 S> */ B(Return),
]
......@@ -103,20 +103,20 @@ snippet: "
"
frame size: 9
parameter count: 1
bytecode array length: 55
bytecode array length: 56
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
/* 59 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(1),
B(JumpIfUndefined), U8(45),
B(JumpIfNull), U8(43),
B(JumpIfUndefined), U8(46),
B(JumpIfNull), U8(44),
B(ToObject), R(3),
B(ForInPrepare), R(3), R(4),
B(LdaZero),
B(Star), R(7),
/* 54 S> */ B(ForInContinue), R(7), R(6),
B(JumpIfFalse), U8(30),
B(JumpIfFalse), U8(31),
B(ForInNext), R(3), R(7), R(4), U8(2),
B(JumpIfUndefined), U8(17),
B(Star), R(1),
......@@ -128,7 +128,7 @@ bytecodes: [
B(Star), R(0),
/* 72 E> */ B(ForInStep), R(7),
B(Star), R(7),
B(Jump), U8(-31),
B(JumpLoop), U8(-31), U8(0),
B(LdaUndefined),
/* 80 S> */ B(Return),
]
......@@ -148,20 +148,20 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 82
bytecode array length: 83
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(1),
B(Mov), R(1), R(0),
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(1),
B(JumpIfUndefined), U8(67),
B(JumpIfNull), U8(65),
B(JumpIfUndefined), U8(68),
B(JumpIfNull), U8(66),
B(ToObject), R(1),
B(ForInPrepare), R(1), R(2),
B(LdaZero),
B(Star), R(5),
/* 68 S> */ B(ForInContinue), R(5), R(4),
B(JumpIfFalse), U8(52),
B(JumpIfFalse), U8(53),
B(ForInNext), R(1), R(5), R(2), U8(11),
B(JumpIfUndefined), U8(39),
B(Star), R(6),
......@@ -178,10 +178,10 @@ bytecodes: [
B(LdaSmi), U8(20),
/* 136 E> */ B(TestEqual), R(7), U8(8),
B(JumpIfFalse), U8(4),
/* 143 S> */ B(Jump), U8(8),
/* 143 S> */ B(Jump), U8(9),
B(ForInStep), R(5),
B(Star), R(5),
B(Jump), U8(-53),
B(JumpLoop), U8(-53), U8(0),
B(LdaUndefined),
/* 152 S> */ B(Return),
]
......@@ -200,20 +200,20 @@ snippet: "
"
frame size: 9
parameter count: 1
bytecode array length: 61
bytecode array length: 62
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(1),
B(Star), R(0),
/* 72 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(1),
B(JumpIfUndefined), U8(48),
B(JumpIfNull), U8(46),
B(JumpIfUndefined), U8(49),
B(JumpIfNull), U8(47),
B(ToObject), R(1),
B(ForInPrepare), R(1), R(2),
B(LdaZero),
B(Star), R(5),
/* 65 S> */ B(ForInContinue), R(5), R(4),
B(JumpIfFalse), U8(33),
B(JumpIfFalse), U8(34),
B(ForInNext), R(1), R(5), R(2), U8(7),
B(JumpIfUndefined), U8(20),
B(Star), R(6),
......@@ -227,7 +227,7 @@ bytecodes: [
/* 98 S> */ B(Return),
B(ForInStep), R(5),
B(Star), R(5),
B(Jump), U8(-34),
B(JumpLoop), U8(-34), U8(0),
B(LdaUndefined),
/* 98 S> */ B(Return),
]
......
......@@ -12,7 +12,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 278
bytecode array length: 279
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
......@@ -33,7 +33,7 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(LdaNamedProperty), R(3), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(23),
B(JumpIfToBooleanTrue), U8(24),
B(LdrNamedProperty), R(3), U8(4), U8(11), R(5),
B(LdaSmi), U8(2),
B(Star), R(4),
......@@ -42,7 +42,7 @@ bytecodes: [
B(Mov), R(0), R(1),
B(LdaZero),
B(Star), R(4),
B(Jump), U8(-49),
B(JumpLoop), U8(-49), U8(0),
B(Jump), U8(37),
B(Star), R(13),
B(Ldar), R(closure),
......@@ -138,9 +138,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[7, 117, 123],
[10, 80, 82],
[200, 210, 212],
[7, 118, 124],
[10, 81, 83],
[201, 211, 213],
]
---
......@@ -296,7 +296,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 296
bytecode array length: 297
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
......@@ -317,7 +317,7 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(LdaNamedProperty), R(3), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(41),
B(JumpIfToBooleanTrue), U8(42),
B(LdrNamedProperty), R(3), U8(4), U8(11), R(5),
B(LdaSmi), U8(2),
B(Star), R(4),
......@@ -331,10 +331,10 @@ bytecodes: [
/* 91 S> */ B(LdaSmi), U8(20),
/* 97 E> */ B(TestEqual), R(1), U8(14),
B(JumpIfFalse), U8(4),
/* 104 S> */ B(Jump), U8(7),
/* 104 S> */ B(Jump), U8(8),
B(LdaZero),
B(Star), R(4),
B(Jump), U8(-67),
B(JumpLoop), U8(-67), U8(0),
B(Jump), U8(37),
B(Star), R(13),
B(Ldar), R(closure),
......@@ -430,9 +430,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[7, 135, 141],
[10, 98, 100],
[218, 228, 230],
[7, 136, 142],
[10, 99, 101],
[219, 229, 231],
]
---
......
......@@ -267,7 +267,7 @@ snippet: "
"
frame size: 18
parameter count: 1
bytecode array length: 805
bytecode array length: 807
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(28),
......@@ -417,14 +417,14 @@ bytecodes: [
B(Star), R(9),
B(LdaZero),
B(Star), R(8),
B(Jump), U8(74),
B(Jump), U8(76),
B(Ldar), R(13),
/* 36 E> */ B(Throw),
B(Ldar), R(13),
B(PopContext), R(2),
B(LdaZero),
B(StaContextSlot), R(1), U8(9), U8(0),
B(Wide), B(Jump), U16(-234),
B(Wide), B(JumpLoop), U16(-234), U16(0),
B(Jump), U8(44),
B(Star), R(12),
B(Ldar), R(closure),
......@@ -585,7 +585,7 @@ constant pool: [
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["x"],
Smi [146],
Smi [167],
Smi [169],
ONE_BYTE_INTERNALIZED_STRING_TYPE [".catch"],
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
......@@ -595,12 +595,12 @@ constant pool: [
Smi [129],
Smi [166],
Smi [155],
Smi [601],
Smi [603],
]
handlers: [
[48, 718, 724],
[153, 458, 464],
[156, 414, 416],
[572, 586, 588],
[48, 720, 726],
[153, 460, 466],
[156, 416, 418],
[574, 588, 590],
]
......@@ -328,7 +328,7 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 1411
bytecode array length: 1412
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
......@@ -959,7 +959,7 @@ bytecodes: [
B(Star), R(1),
/* 4108 S> */ B(LdaSmi), U8(3),
/* 4108 E> */ B(TestLessThan), R(1), U8(1),
B(Wide), B(JumpIfFalse), U16(38),
B(Wide), B(JumpIfFalse), U16(39),
/* 4090 E> */ B(StackCheck),
/* 4122 S> */ B(LdaSmi), U8(1),
/* 4128 E> */ B(TestEqual), R(1), U8(3),
......@@ -968,11 +968,11 @@ bytecodes: [
/* 4146 S> */ B(LdaSmi), U8(2),
/* 4152 E> */ B(TestEqual), R(1), U8(4),
B(Wide), B(JumpIfFalse), U16(7),
/* 4158 S> */ B(Wide), B(Jump), U16(11),
/* 4158 S> */ B(Wide), B(Jump), U16(12),
/* 4114 S> */ B(Ldar), R(1),
B(Inc), U8(2),
B(Star), R(1),
B(Jump), U8(-42),
B(JumpLoop), U8(-42), U8(0),
/* 4167 S> */ B(LdaSmi), U8(3),
/* 4177 S> */ B(Return),
]
......
......@@ -17,7 +17,7 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 27
bytecode array length: 28
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 45 S> */ B(LdaSmi), U8(1),
......@@ -29,8 +29,8 @@ bytecodes: [
/* 86 S> */ B(LdaSmi), U8(10),
/* 95 E> */ B(TestGreaterThan), R(0), U8(2),
B(JumpIfFalse), U8(4),
/* 101 S> */ B(Jump), U8(4),
B(Jump), U8(-17),
/* 101 S> */ B(Jump), U8(5),
B(JumpLoop), U8(-17), U8(0),
/* 110 S> */ B(Ldar), R(0),
/* 123 S> */ B(Return),
]
......
......@@ -16,18 +16,18 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 23
bytecode array length: 24
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
/* 54 S> */ B(LdaSmi), U8(10),
/* 54 E> */ B(TestEqual), R(0), U8(1),
B(JumpIfTrue), U8(11),
B(JumpIfTrue), U8(12),
/* 45 E> */ B(StackCheck),
/* 65 S> */ B(AddSmi), U8(10), R(0), U8(2),
B(Star), R(0),
B(Jump), U8(-14),
B(JumpLoop), U8(-14), U8(0),
/* 79 S> */ B(Ldar), R(0),
/* 89 S> */ B(Return),
]
......@@ -46,7 +46,7 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 19
bytecode array length: 22
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaFalse),
......@@ -57,7 +57,8 @@ bytecodes: [
B(Star), R(0),
/* 74 S> */ B(LdaFalse),
/* 74 E> */ B(TestEqual), R(0), U8(1),
B(JumpIfTrue), U8(-10),
B(JumpIfFalse), U8(5),
B(JumpLoop), U8(-12), U8(0),
/* 85 S> */ B(Ldar), R(0),
/* 95 S> */ B(Return),
]
......
......@@ -892,7 +892,7 @@ snippet: "
"
frame size: 158
parameter count: 1
bytecode array length: 55
bytecode array length: 56
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 1503 S> */ B(LdaZero),
......@@ -903,7 +903,7 @@ bytecodes: [
B(Wide), B(Star), R16(128),
/* 1538 S> */ B(LdaSmi), U8(64),
/* 1538 E> */ B(Wide), B(TestLessThan), R16(128), U16(1),
B(JumpIfFalse), U8(30),
B(JumpIfFalse), U8(31),
/* 1518 E> */ B(StackCheck),
/* 1555 S> */ B(Wide), B(Ldar), R16(128),
/* 1561 E> */ B(Add), R(1), U8(3),
......@@ -912,7 +912,7 @@ bytecodes: [
/* 1548 S> */ B(Wide), B(Ldar), R16(128),
B(Inc), U8(2),
B(Wide), B(Star), R16(128),
B(Jump), U8(-36),
B(JumpLoop), U8(-36), U8(0),
/* 1567 S> */ B(Wide), B(Ldar), R16(128),
/* 1580 S> */ B(Return),
]
......@@ -1086,7 +1086,7 @@ snippet: "
"
frame size: 163
parameter count: 1
bytecode array length: 84
bytecode array length: 85
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 1503 S> */ B(Wide), B(LdaSmi), U16(1234),
......@@ -1094,14 +1094,14 @@ bytecodes: [
/* 1518 S> */ B(LdaZero),
B(Star), R(1),
/* 1534 S> */ B(Ldar), R(0),
B(JumpIfUndefined), U8(69),
B(JumpIfNull), U8(67),
B(JumpIfUndefined), U8(70),
B(JumpIfNull), U8(68),
B(Wide), B(ToObject), R16(157),
B(Wide), B(ForInPrepare), R16(157), R16(158),
B(LdaZero),
B(Wide), B(Star), R16(161),
/* 1526 S> */ B(Wide), B(ForInContinue), R16(161), R16(160),
B(JumpIfFalse), U8(44),
B(JumpIfFalse), U8(45),
B(Wide), B(ForInNext), R16(157), R16(161), R16(158), U16(2),
B(JumpIfUndefined), U8(22),
B(Wide), B(Star), R16(128),
......@@ -1112,7 +1112,7 @@ bytecodes: [
B(Star), R(1),
/* 1544 E> */ B(Wide), B(ForInStep), R16(161),
B(Wide), B(Star), R16(161),
B(Jump), U8(-48),
B(JumpLoop), U8(-48), U8(0),
/* 1553 S> */ B(Ldar), R(1),
/* 1564 S> */ B(Return),
]
......
......@@ -72,7 +72,6 @@ class InitializedIgnitionHandleScope : public InitializedHandleScope {
public:
InitializedIgnitionHandleScope() {
i::FLAG_ignition = true;
i::FLAG_ignition_osr = false; // TODO(4764): Disabled for now.
i::FLAG_always_opt = false;
i::FLAG_allow_natives_syntax = true;
CcTest::i_isolate()->interpreter()->Initialize();
......
......@@ -1408,7 +1408,7 @@ TEST(InterpreterJumps) {
.Jump(&label[2]);
SetRegister(builder, reg, 2048, scratch).Bind(&label[1]);
IncrementRegister(builder, reg, 2, scratch, vector->GetIndex(slot1))
.Jump(&label[0]);
.JumpLoop(&label[0], 0);
SetRegister(builder, reg, 4096, scratch).Bind(&label[2]);
IncrementRegister(builder, reg, 4, scratch, vector->GetIndex(slot2))
.LoadAccumulatorWithRegister(reg)
......
......@@ -44,8 +44,8 @@ class BytecodeArrayWriterUnittest : public TestWithIsolateAndZone {
const BytecodeSourceInfo& info = BytecodeSourceInfo());
void WriteJump(Bytecode bytecode, BytecodeLabel* label,
const BytecodeSourceInfo& info = BytecodeSourceInfo());
void WriteJumpLoop(Bytecode bytecode, BytecodeLabel* label, int depth);
BytecodeArrayWriter* writer() { return &bytecode_array_writer_; }
ZoneVector<unsigned char>* bytecodes() { return writer()->bytecodes(); }
......@@ -111,6 +111,13 @@ void BytecodeArrayWriterUnittest::WriteJump(Bytecode bytecode,
writer()->WriteJump(&node, label);
}
void BytecodeArrayWriterUnittest::WriteJumpLoop(Bytecode bytecode,
BytecodeLabel* label,
int depth) {
BytecodeNode node(bytecode, 0, depth);
writer()->WriteJump(&node, label);
}
TEST_F(BytecodeArrayWriterUnittest, SimpleExample) {
CHECK_EQ(bytecodes()->size(), 0);
......@@ -161,14 +168,14 @@ TEST_F(BytecodeArrayWriterUnittest, ComplexExample) {
/* 0 30 E> */ B(StackCheck),
/* 1 42 S> */ B(LdaConstant), U8(0),
/* 3 42 E> */ B(Star), R8(1),
/* 5 68 S> */ B(JumpIfUndefined), U8(38),
/* 7 */ B(JumpIfNull), U8(36),
/* 5 68 S> */ B(JumpIfUndefined), U8(39),
/* 7 */ B(JumpIfNull), U8(37),
/* 9 */ B(ToObject), R8(3),
/* 11 */ B(ForInPrepare), R8(3), R8(4),
/* 14 */ B(LdaZero),
/* 15 */ B(Star), R8(7),
/* 17 63 S> */ B(ForInContinue), R8(7), R8(6),
/* 20 */ B(JumpIfFalse), U8(23),
/* 20 */ B(JumpIfFalse), U8(24),
/* 22 */ B(ForInNext), R8(3), R8(7), R8(4), U8(1),
/* 27 */ B(JumpIfUndefined), U8(10),
/* 29 */ B(Star), R8(0),
......@@ -178,15 +185,15 @@ TEST_F(BytecodeArrayWriterUnittest, ComplexExample) {
/* 36 85 S> */ B(Return),
/* 37 */ B(ForInStep), R8(7),
/* 39 */ B(Star), R8(7),
/* 41 */ B(Jump), U8(-24),
/* 43 */ B(LdaUndefined),
/* 44 85 S> */ B(Return),
/* 41 */ B(JumpLoop), U8(-24), U8(0),
/* 44 */ B(LdaUndefined),
/* 45 85 S> */ B(Return),
// clang-format on
};
static const PositionTableEntry expected_positions[] = {
{0, 30, false}, {1, 42, true}, {3, 42, false}, {5, 68, true},
{17, 63, true}, {31, 54, false}, {36, 85, true}, {44, 85, true}};
{17, 63, true}, {31, 54, false}, {36, 85, true}, {45, 85, true}};
BytecodeLabel back_jump, jump_for_in, jump_end_1, jump_end_2, jump_end_3;
......@@ -220,7 +227,7 @@ TEST_F(BytecodeArrayWriterUnittest, ComplexExample) {
writer()->BindLabel(&jump_for_in);
Write(Bytecode::kForInStep, R(7));
Write(Bytecode::kStar, R(7));
WriteJump(Bytecode::kJump, &back_jump);
WriteJumpLoop(Bytecode::kJumpLoop, &back_jump, 0);
writer()->BindLabel(&jump_end_1);
writer()->BindLabel(&jump_end_2);
writer()->BindLabel(&jump_end_3);
......
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