[Interpreter] Remove all Ldr style bytecodes and replace with Star lookahead.

We seem to get some small wins from avoiding the Ldr bytecodes, probably due
to reduced icache pressure since there are less bytecode handlers. Replace
the Ldr bytecodes with Star lookahead inlined into the Lda versions.

Also fixes IsAccumulatorLoadWithoutEffects to include LdaContextSlot and
LdaCurrentContextSlot

BUG=v8:4280

Review-Url: https://codereview.chromium.org/2489513005
Cr-Commit-Position: refs/heads/master@{#40883}
This commit is contained in:
rmcilroy 2016-11-10 02:41:48 -08:00 committed by Commit bot
parent 6aa16edf36
commit f633218b62
30 changed files with 312 additions and 481 deletions

View File

@ -708,11 +708,6 @@ void BytecodeGraphBuilder::VisitLdaUndefined() {
environment()->BindAccumulator(node);
}
void BytecodeGraphBuilder::VisitLdrUndefined() {
Node* node = jsgraph()->UndefinedConstant();
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node);
}
void BytecodeGraphBuilder::VisitLdaNull() {
Node* node = jsgraph()->NullConstant();
environment()->BindAccumulator(node);
@ -767,14 +762,6 @@ void BytecodeGraphBuilder::VisitLdaGlobal() {
environment()->BindAccumulator(node, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitLdrGlobal() {
PrepareEagerCheckpoint();
Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0),
TypeofMode::NOT_INSIDE_TYPEOF);
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node,
Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
PrepareEagerCheckpoint();
Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0),
@ -803,7 +790,7 @@ void BytecodeGraphBuilder::VisitStaGlobalStrict() {
BuildStoreGlobal(LanguageMode::STRICT);
}
Node* BytecodeGraphBuilder::BuildLoadContextSlot() {
void BytecodeGraphBuilder::VisitLdaContextSlot() {
// TODO(mythria): immutable flag is also set to false. This information is not
// available in bytecode array. update this code when the implementation
// changes.
@ -812,39 +799,21 @@ Node* BytecodeGraphBuilder::BuildLoadContextSlot() {
bytecode_iterator().GetIndexOperand(1), false);
Node* context =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
return NewNode(op, context);
Node* node = NewNode(op, context);
environment()->BindAccumulator(node);
}
Node* BytecodeGraphBuilder::BuildLoadCurrentContextSlot() {
void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
// TODO(mythria): immutable flag is also set to false. This information is not
// available in bytecode array. update this code when the implementation
// changes.
const Operator* op = javascript()->LoadContext(
0, bytecode_iterator().GetIndexOperand(0), false);
Node* context = environment()->Context();
return NewNode(op, context);
}
void BytecodeGraphBuilder::VisitLdaContextSlot() {
Node* node = BuildLoadContextSlot();
Node* node = NewNode(op, context);
environment()->BindAccumulator(node);
}
void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
Node* node = BuildLoadCurrentContextSlot();
environment()->BindAccumulator(node);
}
void BytecodeGraphBuilder::VisitLdrContextSlot() {
Node* node = BuildLoadContextSlot();
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), node);
}
void BytecodeGraphBuilder::VisitLdrCurrentContextSlot() {
Node* node = BuildLoadCurrentContextSlot();
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node);
}
void BytecodeGraphBuilder::VisitStaContextSlot() {
const Operator* op = javascript()->StoreContext(
bytecode_iterator().GetUnsignedImmediateOperand(2),

View File

@ -134,8 +134,6 @@ class BytecodeGraphBuilder {
void ClearNonLiveSlotsInFrameStates();
void BuildCreateArguments(CreateArgumentsType type);
Node* BuildLoadContextSlot();
Node* BuildLoadCurrentContextSlot();
Node* BuildLoadGlobal(uint32_t feedback_slot_index, TypeofMode typeof_mode);
void BuildStoreGlobal(LanguageMode language_mode);
void BuildNamedStore(LanguageMode language_mode);

View File

@ -116,24 +116,6 @@ bool BytecodePeepholeOptimizer::CanElideLastBasedOnSourcePosition(
namespace {
void TransformLdaStarToLdrLdar(Bytecode new_bytecode, BytecodeNode* const last,
BytecodeNode* const current) {
DCHECK_EQ(current->bytecode(), Bytecode::kStar);
//
// An example transformation here would be:
//
// LdaGlobal i0, i1 ____\ LdrGlobal i0, i1, R
// Star R ====/ Ldar R
//
// which loads a global value into both a register and the
// accumulator. However, in the second form the Ldar can often be
// peephole optimized away unlike the Star in the first form.
//
last->Transform(new_bytecode, current->operand(0));
current->set_bytecode(Bytecode::kLdar, current->operand(0));
}
void TransformLdaSmiBinaryOpToBinaryOpWithSmi(Bytecode new_bytecode,
BytecodeNode* const last,
BytecodeNode* const current) {
@ -239,17 +221,6 @@ void BytecodePeepholeOptimizer::ChangeBytecodeAction(
DefaultAction(node);
}
void BytecodePeepholeOptimizer::TransformLdaStarToLdrLdarAction(
BytecodeNode* const node, const PeepholeActionAndData* action_data) {
DCHECK(LastIsValid());
DCHECK(!Bytecodes::IsJump(node->bytecode()));
if (!node->source_info().is_statement()) {
TransformLdaStarToLdrLdar(action_data->bytecode, last(), node);
}
DefaultAction(node);
}
void BytecodePeepholeOptimizer::TransformLdaSmiBinaryOpToBinaryOpWithSmiAction(
BytecodeNode* const node, const PeepholeActionAndData* action_data) {
DCHECK(LastIsValid());

View File

@ -19,7 +19,6 @@ namespace interpreter {
V(ElideCurrentIfOperand0MatchesAction) \
V(ElideLastAction) \
V(ChangeBytecodeAction) \
V(TransformLdaStarToLdrLdarAction) \
V(TransformLdaSmiBinaryOpToBinaryOpWithSmiAction) \
V(TransformLdaZeroBinaryOpToBinaryOpWithZeroAction)

View File

@ -211,8 +211,12 @@ bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
case Bytecode::kLdaNull:
case Bytecode::kLdaTheHole:
case Bytecode::kLdaConstant:
case Bytecode::kLdaUndefined:
case Bytecode::kLdaGlobal:
case Bytecode::kLdaNamedProperty:
case Bytecode::kLdaKeyedProperty:
case Bytecode::kLdaContextSlot:
case Bytecode::kLdaCurrentContextSlot:
case Bytecode::kAdd:
case Bytecode::kSub:
case Bytecode::kMul:

View File

@ -37,12 +37,8 @@ namespace interpreter {
V(LdaFalse, AccumulatorUse::kWrite) \
V(LdaConstant, AccumulatorUse::kWrite, OperandType::kIdx) \
\
/* Loading registers */ \
V(LdrUndefined, AccumulatorUse::kNone, OperandType::kRegOut) \
\
/* Globals */ \
V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx) \
V(LdrGlobal, AccumulatorUse::kNone, OperandType::kIdx, OperandType::kRegOut) \
V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx) \
V(StaGlobalSloppy, AccumulatorUse::kRead, OperandType::kIdx, \
OperandType::kIdx) \
@ -55,10 +51,6 @@ namespace interpreter {
V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg, \
OperandType::kIdx, OperandType::kUImm) \
V(LdaCurrentContextSlot, AccumulatorUse::kWrite, OperandType::kIdx) \
V(LdrContextSlot, AccumulatorUse::kNone, OperandType::kReg, \
OperandType::kIdx, OperandType::kUImm, OperandType::kRegOut) \
V(LdrCurrentContextSlot, AccumulatorUse::kNone, OperandType::kIdx, \
OperandType::kRegOut) \
V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg, \
OperandType::kIdx, OperandType::kUImm) \
V(StaCurrentContextSlot, AccumulatorUse::kRead, OperandType::kIdx) \
@ -430,15 +422,16 @@ class V8_EXPORT_PRIVATE Bytecodes final {
bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse ||
bytecode == Bytecode::kLdaUndefined ||
bytecode == Bytecode::kLdaTheHole ||
bytecode == Bytecode::kLdaConstant;
bytecode == Bytecode::kLdaConstant ||
bytecode == Bytecode::kLdaContextSlot ||
bytecode == Bytecode::kLdaCurrentContextSlot;
}
// Return true if |bytecode| is a register load without effects,
// e.g. Mov, Star, LdrUndefined.
// e.g. Mov, Star.
static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) {
return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext ||
bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar ||
bytecode == Bytecode::kLdrUndefined;
bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar;
}
// Returns true if the bytecode is a conditional jump taking

View File

@ -352,17 +352,6 @@ void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) {
__ Dispatch();
}
// LdrUndefined <reg>
//
// Loads undefined into the accumulator and |reg|.
void Interpreter::DoLdrUndefined(InterpreterAssembler* assembler) {
Node* undefined_value =
__ HeapConstant(isolate_->factory()->undefined_value());
Node* destination = __ BytecodeOperandReg(0);
__ StoreRegister(undefined_value, destination);
__ Dispatch();
}
// LdaNull
//
// Load Null into the accumulator.
@ -460,23 +449,6 @@ void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) {
__ Dispatch();
}
// LdrGlobal <slot> <reg>
//
// Load the global with name in constant pool entry <name_index> into
// register <reg> using FeedBackVector slot <slot> outside of a typeof.
void Interpreter::DoLdrGlobal(InterpreterAssembler* assembler) {
Callable ic =
CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF);
Node* context = __ GetContext();
Node* raw_slot = __ BytecodeOperandIdx(0);
Node* result = BuildLoadGlobal(ic, context, raw_slot, assembler);
Node* destination = __ BytecodeOperandReg(1);
__ StoreRegister(result, destination);
__ Dispatch();
}
// LdaGlobalInsideTypeof <slot>
//
// Load the global with name in constant pool entry <name_index> into the
@ -534,29 +506,17 @@ void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) {
DoStaGlobal(ic, assembler);
}
compiler::Node* Interpreter::BuildLoadContextSlot(
InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0);
Node* context = __ LoadRegister(reg_index);
Node* slot_index = __ BytecodeOperandIdx(1);
Node* depth = __ BytecodeOperandUImm(2);
Node* slot_context = __ GetContextAtDepth(context, depth);
return __ LoadContextElement(slot_context, slot_index);
}
compiler::Node* Interpreter::BuildLoadCurrentContextSlot(
InterpreterAssembler* assembler) {
Node* slot_index = __ BytecodeOperandIdx(0);
Node* slot_context = __ GetContext();
return __ LoadContextElement(slot_context, slot_index);
}
// LdaContextSlot <context> <slot_index> <depth>
//
// Load the object in |slot_index| of the context at |depth| in the context
// chain starting at |context| into the accumulator.
void Interpreter::DoLdaContextSlot(InterpreterAssembler* assembler) {
Node* result = BuildLoadContextSlot(assembler);
Node* reg_index = __ BytecodeOperandReg(0);
Node* context = __ LoadRegister(reg_index);
Node* slot_index = __ BytecodeOperandIdx(1);
Node* depth = __ BytecodeOperandUImm(2);
Node* slot_context = __ GetContextAtDepth(context, depth);
Node* result = __ LoadContextElement(slot_context, slot_index);
__ SetAccumulator(result);
__ Dispatch();
}
@ -565,32 +525,13 @@ void Interpreter::DoLdaContextSlot(InterpreterAssembler* assembler) {
//
// Load the object in |slot_index| of the current context into the accumulator.
void Interpreter::DoLdaCurrentContextSlot(InterpreterAssembler* assembler) {
Node* result = BuildLoadCurrentContextSlot(assembler);
Node* slot_index = __ BytecodeOperandIdx(0);
Node* slot_context = __ GetContext();
Node* result = __ LoadContextElement(slot_context, slot_index);
__ SetAccumulator(result);
__ Dispatch();
}
// LdrContextSlot <context> <slot_index> <depth> <reg>
//
// Load the object in |slot_index| of the context at |depth| in the context
// chain of |context| into register |reg|.
void Interpreter::DoLdrContextSlot(InterpreterAssembler* assembler) {
Node* result = BuildLoadContextSlot(assembler);
Node* destination = __ BytecodeOperandReg(3);
__ StoreRegister(result, destination);
__ Dispatch();
}
// LdrCurrentContextSlot <slot_index> <reg>
//
// Load the object in |slot_index| of the current context into register |reg|.
void Interpreter::DoLdrCurrentContextSlot(InterpreterAssembler* assembler) {
Node* result = BuildLoadCurrentContextSlot(assembler);
Node* destination = __ BytecodeOperandReg(1);
__ StoreRegister(result, destination);
__ Dispatch();
}
// StaContextSlot <context> <slot_index> <depth>
//
// Stores the object in the accumulator into |slot_index| of the context at

View File

@ -139,12 +139,6 @@ class Interpreter {
void DoStaLookupSlot(LanguageMode language_mode,
InterpreterAssembler* assembler);
// Generates code to load a context slot.
compiler::Node* BuildLoadContextSlot(InterpreterAssembler* assembler);
// Generates code to load a slot in the current context.
compiler::Node* BuildLoadCurrentContextSlot(InterpreterAssembler* assembler);
// Generates code to load a global.
compiler::Node* BuildLoadGlobal(Callable ic, compiler::Node* context,
compiler::Node* feedback_slot,

View File

@ -79,30 +79,6 @@ const char* PeepholeActionTableWriter::kNamespaceElements[] = {"v8", "internal",
// static
PeepholeActionAndData PeepholeActionTableWriter::LookupActionAndData(
Bytecode last, Bytecode current) {
// Optimize various accumulator loads followed by store accumulator
// to an equivalent register load and loading the accumulator with
// the register. The latter accumulator load can often be elided as
// it is side-effect free and often followed by another accumulator
// load so can be elided.
if (current == Bytecode::kStar) {
switch (last) {
case Bytecode::kLdaGlobal:
return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
Bytecode::kLdrGlobal};
case Bytecode::kLdaContextSlot:
return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
Bytecode::kLdrContextSlot};
case Bytecode::kLdaCurrentContextSlot:
return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
Bytecode::kLdrCurrentContextSlot};
case Bytecode::kLdaUndefined:
return {PeepholeAction::kTransformLdaStarToLdrLdarAction,
Bytecode::kLdrUndefined};
default:
break;
}
}
// ToName bytecodes can be replaced by Star with the same output register if
// the value in the accumulator is already a name.
if (current == Bytecode::kToName && Bytecodes::PutsNameInAccumulator(last)) {

View File

@ -14,11 +14,13 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 12
bytecode array length: 14
bytecodes: [
/* 27 E> */ B(StackCheck),
/* 32 S> */ B(LdrUndefined), R(1),
B(LdrGlobal), U8(4), R(0),
/* 32 S> */ B(LdaUndefined),
B(Star), R(1),
B(LdaGlobal), U8(4),
B(Star), R(0),
/* 39 E> */ B(Call), R(0), R(1), U8(1), U8(2),
/* 44 S> */ B(Return),
]
@ -35,11 +37,13 @@ snippet: "
"
frame size: 5
parameter count: 1
bytecode array length: 24
bytecode array length: 26
bytecodes: [
/* 34 E> */ B(StackCheck),
/* 39 S> */ B(LdrUndefined), R(1),
B(LdrGlobal), U8(4), R(0),
/* 39 S> */ B(LdaUndefined),
B(Star), R(1),
B(LdaGlobal), U8(4),
B(Star), R(0),
B(LdaSmi), U8(1),
B(Star), R(2),
B(LdaSmi), U8(2),

View File

@ -14,11 +14,11 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 12
bytecode array length: 11
bytecodes: [
/* 45 E> */ B(StackCheck),
/* 50 S> */ B(LdrGlobal), U8(4), R(0),
B(Ldar), R(0),
/* 50 S> */ B(LdaGlobal), U8(4),
B(Star), R(0),
/* 57 E> */ B(New), R(0), R(0), U8(0), U8(2),
/* 68 S> */ B(Return),
]
@ -35,10 +35,11 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 16
bytecode array length: 17
bytecodes: [
/* 58 E> */ B(StackCheck),
/* 63 S> */ B(LdrGlobal), U8(4), R(0),
/* 63 S> */ B(LdaGlobal), U8(4),
B(Star), R(0),
B(LdaSmi), U8(3),
B(Star), R(1),
B(Ldar), R(0),
@ -63,10 +64,11 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 24
bytecode array length: 25
bytecodes: [
/* 100 E> */ B(StackCheck),
/* 105 S> */ B(LdrGlobal), U8(4), R(0),
/* 105 S> */ B(LdaGlobal), U8(4),
B(Star), R(0),
B(LdaSmi), U8(3),
B(Star), R(1),
B(LdaSmi), U8(4),

View File

@ -72,10 +72,11 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 14
bytecode array length: 15
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 15 S> */ B(LdrUndefined), R(0),
/* 15 S> */ B(LdaUndefined),
B(Star), R(0),
B(CreateArrayLiteral), U8(0), U8(0), U8(9),
B(Star), R(1),
B(CallJSRuntime), U8(150), R(0), U8(2),

View File

@ -149,8 +149,8 @@ bytecodes: [
B(Star), R(4),
B(LdaNamedProperty), R(4), U8(3), U8(2),
B(Star), R(5),
/* 75 E> */ B(LdaCurrentContextSlot), U8(4),
B(ToName), R(7),
B(LdaCurrentContextSlot), U8(4),
/* 75 E> */ B(ToName), R(7),
B(CreateClosure), U8(4), U8(2),
B(Star), R(8),
B(LdaSmi), U8(2),
@ -159,8 +159,8 @@ bytecodes: [
B(Star), R(10),
B(Mov), R(5), R(6),
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(6), U8(5),
/* 106 E> */ B(LdaCurrentContextSlot), U8(5),
B(ToName), R(7),
B(LdaCurrentContextSlot), U8(5),
/* 106 E> */ B(ToName), R(7),
B(LdaConstant), U8(3),
B(TestEqualStrict), R(7), U8(0),
B(Mov), R(4), R(6),

View File

@ -109,7 +109,7 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 23
bytecode array length: 24
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
@ -117,7 +117,8 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(1),
/* 42 E> */ B(StaCurrentContextSlot), U8(4),
/* 45 S> */ B(CreateClosure), U8(0), U8(2),
/* 75 S> */ B(LdrCurrentContextSlot), U8(4), R(1),
/* 75 S> */ B(LdaCurrentContextSlot), U8(4),
B(Star), R(1),
B(BitwiseOrSmi), U8(24), R(1), U8(2),
/* 77 E> */ B(StaCurrentContextSlot), U8(4),
B(LdaUndefined),

View File

@ -74,11 +74,11 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 47 S> */ B(LdaSmi), U8(20),
B(Star), R(2),
/* 47 E> */ B(LdaCurrentContextSlot), U8(4),
B(LdaCurrentContextSlot), U8(4),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(1),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
/* 47 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), U8(0),
/* 47 E> */ B(StaCurrentContextSlot), U8(4),
B(LdaUndefined),

View File

@ -77,12 +77,13 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 20
bytecode array length: 21
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 41 S> */ B(LdrUndefined), R(2),
/* 41 S> */ B(LdaUndefined),
B(Star), R(2),
B(CreateClosure), U8(0), U8(2),
B(Star), R(1),
/* 64 E> */ B(Call), R(1), R(2), U8(1), U8(2),
@ -389,7 +390,7 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 789
bytecode array length: 791
bytecodes: [
B(CreateFunctionContext), U8(254),
B(PushContext), R(0),
@ -900,8 +901,10 @@ bytecodes: [
/* 3421 E> */ B(StaCurrentContextSlot), U8(254),
/* 3435 S> */ B(LdaZero),
/* 3435 E> */ B(StaCurrentContextSlot), U8(255),
/* 3438 S> */ B(LdrUndefined), R(2),
/* 3438 E> */ B(LdrGlobal), U8(4), R(1),
/* 3438 S> */ B(LdaUndefined),
B(Star), R(2),
/* 3438 E> */ B(LdaGlobal), U8(4),
B(Star), R(1),
/* 3438 E> */ B(Call), R(1), R(2), U8(1), U8(2),
/* 3454 S> */ B(LdaSmi), U8(100),
/* 3454 E> */ B(Wide), B(StaCurrentContextSlot), U16(256),

View File

@ -104,7 +104,7 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 29
bytecode array length: 31
bytecodes: [
B(LdaConstant), U8(0),
B(Star), R(1),
@ -113,8 +113,10 @@ bytecodes: [
B(Mov), R(closure), R(3),
B(CallRuntime), U16(Runtime::kDeclareGlobalsForInterpreter), R(1), U8(3),
/* 0 E> */ B(StackCheck),
/* 16 S> */ B(LdrUndefined), R(2),
B(LdrGlobal), U8(2), R(1),
/* 16 S> */ B(LdaUndefined),
B(Star), R(2),
B(LdaGlobal), U8(2),
B(Star), R(1),
/* 16 E> */ B(Call), R(1), R(2), U8(1), U8(4),
B(Star), R(0),
/* 20 S> */ B(Return),

View File

@ -98,7 +98,7 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 25
bytecode array length: 26
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
@ -107,7 +107,8 @@ bytecodes: [
B(Ldar), R(1),
/* 56 E> */ B(StaCurrentContextSlot), U8(4),
/* 64 S> */ B(CreateClosure), U8(1), U8(2),
/* 93 S> */ B(LdrCurrentContextSlot), U8(4), R(1),
/* 93 S> */ B(LdaCurrentContextSlot), U8(4),
B(Star), R(1),
B(LdaSmi), U8(1),
B(DeletePropertyStrict), R(1),
/* 113 S> */ B(Return),

View File

@ -30,13 +30,13 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 13
bytecode array length: 12
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 55 S> */ B(LdaSmi), U8(100),
B(Star), R(0),
/* 42 S> */ B(LdrUndefined), R(1),
B(Ldar), R(1),
/* 42 S> */ B(LdaUndefined),
B(Star), R(1),
B(Star), R(2),
/* 63 S> */ B(Nop),
/* 73 S> */ B(Return),

View File

@ -11,7 +11,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 281
bytecode array length: 282
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
@ -45,7 +45,7 @@ bytecodes: [
B(LdaZero),
B(Star), R(4),
B(JumpLoop), U8(-51), U8(0),
B(Jump), U8(35),
B(Jump), U8(36),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(5), U8(6),
@ -56,7 +56,8 @@ bytecodes: [
B(JumpIfFalse), U8(6),
B(LdaSmi), U8(1),
B(Star), R(4),
B(LdrCurrentContextSlot), U8(4), R(13),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kReThrow), R(13), U8(1),
B(PopContext), R(8),
B(LdaSmi), U8(-1),
@ -141,9 +142,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[7, 119, 125],
[7, 120, 126],
[10, 84, 86],
[203, 213, 215],
[204, 214, 216],
]
---
@ -153,7 +154,7 @@ snippet: "
"
frame size: 16
parameter count: 1
bytecode array length: 292
bytecode array length: 293
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
@ -187,8 +188,8 @@ bytecodes: [
/* 73 S> */ B(LdaZero),
B(Star), R(10),
B(Mov), R(1), R(11),
B(Jump), U8(49),
B(Jump), U8(35),
B(Jump), U8(50),
B(Jump), U8(36),
B(Star), R(14),
B(Ldar), R(closure),
B(CreateCatchContext), R(14), U8(5), U8(6),
@ -199,7 +200,8 @@ bytecodes: [
B(JumpIfFalse), U8(6),
B(LdaSmi), U8(1),
B(Star), R(5),
B(LdrCurrentContextSlot), U8(4), R(14),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(14),
B(CallRuntime), U16(Runtime::kReThrow), R(14), U8(1),
B(PopContext), R(9),
B(LdaSmi), U8(-1),
@ -289,9 +291,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[11, 119, 125],
[11, 120, 126],
[14, 84, 86],
[204, 214, 216],
[205, 215, 217],
]
---
@ -303,7 +305,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 299
bytecode array length: 300
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
@ -345,7 +347,7 @@ bytecodes: [
B(LdaZero),
B(Star), R(4),
B(JumpLoop), U8(-69), U8(0),
B(Jump), U8(35),
B(Jump), U8(36),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(5), U8(6),
@ -356,7 +358,8 @@ bytecodes: [
B(JumpIfFalse), U8(6),
B(LdaSmi), U8(1),
B(Star), R(4),
B(LdrCurrentContextSlot), U8(4), R(13),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kReThrow), R(13), U8(1),
B(PopContext), R(8),
B(LdaSmi), U8(-1),
@ -441,9 +444,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[7, 137, 143],
[7, 138, 144],
[10, 102, 104],
[221, 231, 233],
[222, 232, 234],
]
---
@ -453,7 +456,7 @@ snippet: "
"
frame size: 14
parameter count: 1
bytecode array length: 306
bytecode array length: 307
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(8),
@ -491,8 +494,8 @@ bytecodes: [
B(Star), R(9),
B(LdaZero),
B(Star), R(8),
B(Jump), U8(49),
B(Jump), U8(35),
B(Jump), U8(50),
B(Jump), U8(36),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(7), U8(8),
@ -503,7 +506,8 @@ bytecodes: [
B(JumpIfFalse), U8(6),
B(LdaSmi), U8(1),
B(Star), R(3),
B(LdrCurrentContextSlot), U8(4), R(12),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kReThrow), R(12), U8(1),
B(PopContext), R(7),
B(LdaSmi), U8(-1),
@ -595,8 +599,8 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[15, 133, 139],
[15, 134, 140],
[18, 98, 100],
[218, 228, 230],
[219, 229, 231],
]

View File

@ -29,10 +29,11 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 14
bytecode array length: 15
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdrUndefined), R(1),
/* 34 S> */ B(LdaUndefined),
B(Star), R(1),
B(CreateClosure), U8(0), U8(2),
B(Star), R(0),
/* 56 E> */ B(Call), R(0), R(1), U8(1), U8(2),
@ -50,10 +51,11 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 18
bytecode array length: 19
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdrUndefined), R(1),
/* 34 S> */ B(LdaUndefined),
B(Star), R(1),
B(CreateClosure), U8(0), U8(2),
B(Star), R(0),
B(LdaSmi), U8(1),

View File

@ -13,7 +13,7 @@ snippet: "
"
frame size: 11
parameter count: 1
bytecode array length: 202
bytecode array length: 204
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(21),
@ -33,13 +33,14 @@ bytecodes: [
B(StaCurrentContextSlot), U8(4),
/* 11 E> */ B(StackCheck),
B(Mov), R(context), R(4),
/* 11 E> */ B(LdrCurrentContextSlot), U8(4), R(6),
B(Ldar), R(6),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(6),
B(Mov), R(closure), R(5),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(5), U8(2),
/* 11 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(5), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(5),
B(LdrCurrentContextSlot), U8(5), R(6),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(6),
B(LdaZero),
B(SuspendGenerator), R(6),
B(Ldar), R(5),
@ -64,10 +65,11 @@ bytecodes: [
B(Star), R(3),
B(LdaZero),
B(Star), R(2),
B(Jump), U8(35),
B(Jump), U8(36),
B(Ldar), R(7),
/* 11 E> */ B(Throw),
B(LdrUndefined), R(5),
B(LdaUndefined),
B(Star), R(5),
B(LdaTrue),
B(Star), R(6),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(5), U8(2),
@ -83,7 +85,8 @@ bytecodes: [
B(Star), R(2),
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
B(Star), R(4),
B(LdrCurrentContextSlot), U8(5), R(5),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(5),
B(CallRuntime), U16(Runtime::k_GeneratorClose), R(5), U8(1),
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(4), U8(1),
B(LdaZero),
@ -108,7 +111,7 @@ bytecodes: [
constant pool: [
]
handlers: [
[39, 137, 143],
[39, 138, 144],
]
---
@ -118,7 +121,7 @@ snippet: "
"
frame size: 11
parameter count: 1
bytecode array length: 298
bytecode array length: 301
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(28),
@ -141,13 +144,14 @@ bytecodes: [
B(StaCurrentContextSlot), U8(4),
/* 11 E> */ B(StackCheck),
B(Mov), R(context), R(4),
/* 11 E> */ B(LdrCurrentContextSlot), U8(4), R(6),
B(Ldar), R(6),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(6),
B(Mov), R(closure), R(5),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(5), U8(2),
/* 11 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(5), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(5),
B(LdrCurrentContextSlot), U8(5), R(6),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(6),
B(LdaZero),
B(SuspendGenerator), R(6),
B(Ldar), R(5),
@ -172,7 +176,7 @@ bytecodes: [
B(Star), R(3),
B(LdaZero),
B(Star), R(2),
B(Jump), U8(114),
B(Jump), U8(116),
B(Ldar), R(7),
/* 11 E> */ B(Throw),
/* 16 S> */ B(LdaSmi), U8(42),
@ -181,7 +185,8 @@ bytecodes: [
B(Star), R(6),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(5), U8(2),
B(Star), R(5),
B(LdrCurrentContextSlot), U8(5), R(6),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(6),
B(LdaSmi), U8(1),
B(SuspendGenerator), R(6),
B(Ldar), R(5),
@ -206,10 +211,11 @@ bytecodes: [
B(Star), R(3),
B(LdaSmi), U8(1),
B(Star), R(2),
B(Jump), U8(35),
B(Jump), U8(36),
B(Ldar), R(7),
/* 16 E> */ B(Throw),
B(LdrUndefined), R(5),
B(LdaUndefined),
B(Star), R(5),
B(LdaTrue),
B(Star), R(6),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(5), U8(2),
@ -225,7 +231,8 @@ bytecodes: [
B(Star), R(2),
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
B(Star), R(4),
B(LdrCurrentContextSlot), U8(5), R(5),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(5),
B(CallRuntime), U16(Runtime::k_GeneratorClose), R(5), U8(1),
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(4), U8(1),
B(LdaZero),
@ -253,10 +260,10 @@ bytecodes: [
/* 25 S> */ B(Return),
]
constant pool: [
Smi [131],
Smi [132],
]
handlers: [
[46, 223, 229],
[46, 225, 231],
]
---
@ -266,7 +273,7 @@ snippet: "
"
frame size: 18
parameter count: 1
bytecode array length: 775
bytecode array length: 796
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(28),
@ -289,13 +296,14 @@ bytecodes: [
B(StaCurrentContextSlot), U8(4),
/* 11 E> */ B(StackCheck),
B(Mov), R(context), R(7),
/* 11 E> */ B(LdrCurrentContextSlot), U8(4), R(9),
B(Ldar), R(9),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(9),
B(Mov), R(closure), R(8),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(8), U8(2),
/* 11 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(8), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(8),
B(LdrCurrentContextSlot), U8(5), R(9),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(9),
B(LdaZero),
B(SuspendGenerator), R(9),
B(Ldar), R(8),
@ -320,7 +328,7 @@ bytecodes: [
B(Star), R(6),
B(LdaZero),
B(Star), R(5),
B(JumpConstant), U8(17),
B(JumpConstant), U8(19),
B(Ldar), R(10),
/* 11 E> */ B(Throw),
B(Ldar), R(closure),
@ -348,7 +356,8 @@ bytecodes: [
B(LdaSmi), U8(76),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kAbort), R(12), U8(1),
/* 27 S> */ B(LdrContextSlot), R(1), U8(7), U8(0), R(14),
/* 27 S> */ B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(14),
B(LdaNamedProperty), R(14), U8(4), U8(8),
B(Star), R(13),
/* 27 E> */ B(CallProperty), R(13), R(14), U8(1), U8(6),
@ -356,13 +365,16 @@ bytecodes: [
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(12), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(12),
B(LdrContextSlot), R(1), U8(8), U8(0), R(12),
B(JumpIfFalse), U8(13),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdrContextSlot), R(1), U8(8), U8(0), R(12),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(5), U8(10),
B(JumpIfToBooleanTrueConstant), U8(3),
B(LdrContextSlot), R(1), U8(8), U8(0), R(12),
B(JumpIfToBooleanTrueConstant), U8(9),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(6), U8(12),
B(StaContextSlot), R(1), U8(10), U8(0),
B(LdaSmi), U8(2),
@ -377,12 +389,14 @@ bytecodes: [
B(StaCurrentContextSlot), U8(4),
B(LdaContextSlot), R(1), U8(6), U8(0),
B(StaCurrentContextSlot), U8(4),
/* 36 S> */ B(LdrCurrentContextSlot), U8(4), R(12),
/* 36 S> */ B(LdaCurrentContextSlot), U8(4),
B(Star), R(12),
B(LdaFalse),
B(Star), R(13),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(12), U8(2),
B(Star), R(12),
B(LdrContextSlot), R(1), U8(5), U8(0), R(13),
B(LdaContextSlot), R(1), U8(5), U8(0),
B(Star), R(13),
B(LdaSmi), U8(1),
B(SuspendGenerator), R(13),
B(Ldar), R(12),
@ -413,26 +427,28 @@ bytecodes: [
B(Star), R(9),
B(LdaZero),
B(Star), R(8),
B(Jump), U8(72),
B(Jump), U8(74),
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(-215), U16(0),
B(Jump), U8(42),
B(Wide), B(JumpLoop), U16(-221), U16(0),
B(Jump), U8(44),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(9), U8(10),
B(CreateCatchContext), R(12), U8(10), U8(11),
B(Star), R(11),
B(PushContext), R(2),
B(LdrContextSlot), R(0), U8(9), U8(0), R(12),
B(LdaContextSlot), R(0), U8(9), U8(0),
B(Star), R(12),
B(LdaSmi), U8(2),
B(TestEqualStrict), R(12), U8(14),
B(JumpIfFalse), U8(8),
B(LdaSmi), U8(1),
B(StaContextSlot), R(0), U8(9), U8(0),
B(LdrCurrentContextSlot), U8(4), R(12),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kReThrow), R(12), U8(1),
B(PopContext), R(2),
B(LdaSmi), U8(-1),
@ -443,62 +459,73 @@ bytecodes: [
B(Star), R(8),
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
B(Star), R(10),
B(LdrContextSlot), R(1), U8(9), U8(0), R(11),
B(LdaContextSlot), R(1), U8(9), U8(0),
B(Star), R(11),
B(LdaZero),
B(TestEqualStrict), R(11), U8(15),
B(JumpIfTrueConstant), U8(15),
B(LdrContextSlot), R(1), U8(7), U8(0), R(11),
B(JumpIfTrueConstant), U8(17),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(11),
B(LdaUndefined),
B(TestEqualStrict), R(11), U8(16),
B(JumpIfTrueConstant), U8(16),
B(LdrContextSlot), R(1), U8(7), U8(0), R(11),
B(LdaNamedProperty), R(11), U8(11), U8(17),
B(JumpIfTrueConstant), U8(18),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(11),
B(LdaNamedProperty), R(11), U8(12), U8(17),
B(StaContextSlot), R(1), U8(11), U8(0),
B(LdrContextSlot), R(1), U8(11), U8(0), R(11),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(Star), R(11),
B(LdaNull),
B(TestEqual), R(11), U8(19),
B(JumpIfFalse), U8(4),
B(JumpConstant), U8(8),
B(LdrContextSlot), R(1), U8(9), U8(0), R(11),
B(JumpConstant), U8(16),
B(LdaContextSlot), R(1), U8(9), U8(0),
B(Star), R(11),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(11), U8(20),
B(JumpIfFalse), U8(76),
B(JumpIfFalse), U8(78),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(TypeOf),
B(Star), R(11),
B(LdaConstant), U8(12),
B(LdaConstant), U8(13),
B(TestEqualStrict), R(11), U8(21),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(11),
B(LdaConstant), U8(13),
B(LdaConstant), U8(14),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(Throw),
B(Mov), R(context), R(11),
B(LdrContextSlot), R(1), U8(11), U8(0), R(12),
B(LdrContextSlot), R(1), U8(7), U8(0), R(13),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(Star), R(12),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
B(Jump), U8(23),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(9), U8(14),
B(CreateCatchContext), R(12), U8(10), U8(15),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
B(Ldar), R(11),
B(PushContext), R(2),
B(PopContext), R(2),
B(Jump), U8(43),
B(LdrContextSlot), R(1), U8(11), U8(0), R(11),
B(LdrContextSlot), R(1), U8(7), U8(0), R(12),
B(Jump), U8(47),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(Star), R(11),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
B(StaContextSlot), R(1), U8(12), U8(0),
B(LdrContextSlot), R(1), U8(12), U8(0), R(11),
B(LdaContextSlot), R(1), U8(12), U8(0),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(11), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(12),
B(LdrContextSlot), R(1), U8(12), U8(0), R(11),
B(Jump), U8(13),
B(LdaContextSlot), R(1), U8(12), U8(0),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(10), U8(1),
B(LdaZero),
@ -513,15 +540,16 @@ bytecodes: [
B(LdaSmi), U8(1),
B(Star), R(5),
B(Mov), R(9), R(6),
B(Jump), U8(47),
B(Jump), U8(48),
B(PopContext), R(1),
B(PopContext), R(1),
B(LdaSmi), U8(2),
B(Star), R(5),
B(Mov), R(9), R(6),
B(Jump), U8(34),
B(Jump), U8(35),
B(PopContext), R(1),
B(LdrUndefined), R(8),
B(LdaUndefined),
B(Star), R(8),
B(LdaTrue),
B(Star), R(9),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(8), U8(2),
@ -537,7 +565,8 @@ bytecodes: [
B(Star), R(5),
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
B(Star), R(7),
B(LdrCurrentContextSlot), U8(5), R(8),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(8),
B(CallRuntime), U16(Runtime::k_GeneratorClose), R(8), U8(1),
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(7), U8(1),
B(LdaZero),
@ -578,21 +607,23 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
FIXED_ARRAY_TYPE,
Smi [129],
Smi [135],
Smi [152],
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 [166],
Smi [155],
Smi [581],
Smi [136],
Smi [176],
Smi [164],
Smi [601],
]
handlers: [
[46, 690, 696],
[143, 430, 436],
[146, 388, 390],
[544, 558, 560],
[46, 710, 716],
[143, 438, 444],
[146, 394, 396],
[557, 573, 575],
]

View File

@ -14,10 +14,11 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 12
bytecode array length: 13
bytecodes: [
/* 26 E> */ B(StackCheck),
/* 31 S> */ B(LdrGlobal), U8(2), R(0),
/* 31 S> */ B(LdaGlobal), U8(2),
B(Star), R(0),
B(BitwiseAndSmi), U8(1), R(0), U8(4),
/* 45 E> */ B(StaGlobalSloppy), U8(0), U8(5),
/* 51 S> */ B(Return),
@ -36,10 +37,11 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 12
bytecode array length: 13
bytecodes: [
/* 27 E> */ B(StackCheck),
/* 32 S> */ B(LdrGlobal), U8(2), R(0),
/* 32 S> */ B(LdaGlobal), U8(2),
B(Star), R(0),
B(AddSmi), U8(1), R(0), U8(4),
/* 51 E> */ B(StaGlobalSloppy), U8(0), U8(5),
/* 57 S> */ B(Return),

View File

@ -16,10 +16,11 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 9
bytecode array length: 10
bytecodes: [
/* 32 E> */ B(StackCheck),
/* 39 S> */ B(LdrGlobal), U8(2), R(0),
/* 39 S> */ B(LdaGlobal), U8(2),
B(Star), R(0),
B(LdaConstant), U8(0),
B(DeletePropertySloppy), R(0),
/* 58 S> */ B(Return),
@ -41,10 +42,11 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 9
bytecode array length: 10
bytecodes: [
/* 28 E> */ B(StackCheck),
/* 51 S> */ B(LdrGlobal), U8(2), R(0),
/* 51 S> */ B(LdaGlobal), U8(2),
B(Star), R(0),
B(LdaSmi), U8(1),
B(DeletePropertyStrict), R(0),
/* 71 S> */ B(Return),
@ -64,11 +66,13 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 14
bytecode array length: 16
bytecodes: [
/* 32 E> */ B(StackCheck),
/* 39 S> */ B(LdrCurrentContextSlot), U8(3), R(0),
B(LdrContextSlot), R(0), U8(2), U8(0), R(1),
/* 39 S> */ B(LdaCurrentContextSlot), U8(3),
B(Star), R(0),
B(LdaContextSlot), R(0), U8(2), U8(0),
B(Star), R(1),
B(LdaConstant), U8(0),
B(DeletePropertySloppy), R(1),
/* 56 S> */ B(Return),
@ -89,11 +93,13 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 14
bytecode array length: 16
bytecodes: [
/* 18 E> */ B(StackCheck),
/* 25 S> */ B(LdrCurrentContextSlot), U8(3), R(0),
B(LdrContextSlot), R(0), U8(2), U8(0), R(1),
/* 25 S> */ B(LdaCurrentContextSlot), U8(3),
B(Star), R(0),
B(LdaContextSlot), R(0), U8(2), U8(0),
B(Star), R(1),
B(LdaConstant), U8(0),
B(DeletePropertySloppy), R(1),
/* 42 S> */ B(Return),

View File

@ -74,11 +74,11 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 45 S> */ B(LdaSmi), U8(20),
B(Star), R(2),
/* 45 E> */ B(LdaCurrentContextSlot), U8(4),
B(LdaCurrentContextSlot), U8(4),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(1),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
/* 45 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
B(Ldar), R(2),
B(StaCurrentContextSlot), U8(4),
/* 45 E> */ B(StaCurrentContextSlot), U8(4),

View File

@ -36,13 +36,14 @@ bytecodes: [
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(3),
B(Ldar), R(3),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(3),
B(Mov), R(closure), R(2),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(2),
B(LdrCurrentContextSlot), U8(5), R(3),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdaZero),
B(SuspendGenerator), R(3),
B(Ldar), R(2),
@ -105,13 +106,14 @@ bytecodes: [
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(3),
B(Ldar), R(3),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(3),
B(Mov), R(closure), R(2),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(2),
B(LdrCurrentContextSlot), U8(5), R(3),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdaZero),
B(SuspendGenerator), R(3),
B(Ldar), R(2),
@ -153,7 +155,7 @@ snippet: "
"
frame size: 9
parameter count: 2
bytecode array length: 193
bytecode array length: 195
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(21),
@ -176,13 +178,14 @@ bytecodes: [
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(4),
B(Ldar), R(4),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(4),
B(Mov), R(closure), R(3),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdrCurrentContextSlot), U8(5), R(4),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(4),
B(LdaZero),
B(SuspendGenerator), R(4),
B(Ldar), R(3),
@ -207,7 +210,8 @@ bytecodes: [
/* 64 S> */ B(Return),
B(Ldar), R(5),
/* 0 E> */ B(Throw),
/* 32 S> */ B(LdrUndefined), R(4),
/* 32 S> */ B(LdaUndefined),
B(Star), R(4),
/* 32 E> */ B(LdaModuleVariable), U8(-1), U8(0),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(1),
@ -224,7 +228,8 @@ bytecodes: [
B(StaCurrentContextSlot), U8(4),
/* 47 S> */ B(LdaUndefined),
/* 47 E> */ B(StaCurrentContextSlot), U8(4),
/* 52 S> */ B(LdrUndefined), R(4),
/* 52 S> */ B(LdaUndefined),
B(Star), R(4),
/* 52 E> */ B(LdaModuleVariable), U8(-1), U8(1),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(1),
@ -277,13 +282,14 @@ bytecodes: [
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(4),
B(Ldar), R(4),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(4),
B(Mov), R(closure), R(3),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdrCurrentContextSlot), U8(5), R(4),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(4),
B(LdaZero),
B(SuspendGenerator), R(4),
B(Ldar), R(3),
@ -367,13 +373,14 @@ bytecodes: [
B(LdaTheHole),
B(StaModuleVariable), U8(1), U8(0),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(4),
B(Ldar), R(4),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(4),
B(Mov), R(closure), R(3),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdrCurrentContextSlot), U8(5), R(4),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(4),
B(LdaZero),
B(SuspendGenerator), R(4),
B(Ldar), R(3),
@ -457,13 +464,14 @@ bytecodes: [
B(LdaTheHole),
B(StaModuleVariable), U8(1), U8(0),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(4),
B(Ldar), R(4),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(4),
B(Mov), R(closure), R(3),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdrCurrentContextSlot), U8(5), R(4),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(4),
B(LdaZero),
B(SuspendGenerator), R(4),
B(Ldar), R(3),
@ -545,13 +553,14 @@ bytecodes: [
B(LdaTheHole),
B(StaModuleVariable), U8(1), U8(0),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(3),
B(Ldar), R(3),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(3),
B(Mov), R(closure), R(2),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(2),
B(LdrCurrentContextSlot), U8(5), R(3),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdaZero),
B(SuspendGenerator), R(3),
B(Ldar), R(2),
@ -619,13 +628,14 @@ bytecodes: [
B(LdaTheHole),
B(StaModuleVariable), U8(1), U8(0),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(3),
B(Ldar), R(3),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(3),
B(Mov), R(closure), R(2),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(2),
B(LdrCurrentContextSlot), U8(5), R(3),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdaZero),
B(SuspendGenerator), R(3),
B(Ldar), R(2),
@ -664,8 +674,8 @@ bytecodes: [
B(Star), R(3),
B(CallRuntime), U16(Runtime::kToFastProperties), R(2), U8(1),
B(StaCurrentContextSlot), U8(6),
/* 16 E> */ B(LdaCurrentContextSlot), U8(6),
B(StaModuleVariable), U8(1), U8(0),
B(LdaCurrentContextSlot), U8(6),
/* 16 E> */ B(StaModuleVariable), U8(1), U8(0),
B(LdaUndefined),
/* 26 S> */ B(Return),
]
@ -706,13 +716,14 @@ bytecodes: [
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(3),
B(Ldar), R(3),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(3),
B(Mov), R(closure), R(2),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(2),
B(LdrCurrentContextSlot), U8(5), R(3),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdaZero),
B(SuspendGenerator), R(3),
B(Ldar), R(2),
@ -775,13 +786,14 @@ bytecodes: [
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(3),
B(Ldar), R(3),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(3),
B(Mov), R(closure), R(2),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(2),
B(LdrCurrentContextSlot), U8(5), R(3),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdaZero),
B(SuspendGenerator), R(3),
B(Ldar), R(2),
@ -822,7 +834,7 @@ snippet: "
"
frame size: 8
parameter count: 2
bytecode array length: 161
bytecode array length: 164
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(21),
@ -849,13 +861,14 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kGetModuleNamespace), R(2), U8(1),
B(StaCurrentContextSlot), U8(6),
/* 0 E> */ B(StackCheck),
/* 0 E> */ B(LdrCurrentContextSlot), U8(4), R(3),
B(Ldar), R(3),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(3),
B(Mov), R(closure), R(2),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
/* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Star), R(2),
B(LdrCurrentContextSlot), U8(5), R(3),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
B(LdaZero),
B(SuspendGenerator), R(3),
B(Ldar), R(2),
@ -880,11 +893,14 @@ bytecodes: [
/* 45 S> */ B(Return),
B(Ldar), R(4),
/* 0 E> */ B(Throw),
/* 27 S> */ B(LdrCurrentContextSlot), U8(6), R(3),
/* 27 S> */ B(LdaCurrentContextSlot), U8(6),
B(Star), R(3),
/* 30 E> */ B(LdaNamedProperty), R(3), U8(1), U8(4),
B(Star), R(2),
/* 33 E> */ B(LdrCurrentContextSlot), U8(6), R(4),
/* 38 E> */ B(LdrCurrentContextSlot), U8(6), R(6),
B(LdaCurrentContextSlot), U8(6),
B(Star), R(4),
B(LdaCurrentContextSlot), U8(6),
B(Star), R(6),
/* 41 E> */ B(LdaNamedProperty), R(6), U8(2), U8(6),
B(Star), R(5),
/* 31 E> */ B(CallProperty), R(2), R(3), U8(3), U8(2),

View File

@ -20,12 +20,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 12
bytecode array length: 13
bytecodes: [
/* 97 E> */ B(StackCheck),
/* 102 S> */ B(LdrContextSlot), R(context), U8(4), U8(1), R(0),
/* 120 E> */ B(LdaCurrentContextSlot), U8(4),
B(Mul), R(0), U8(2),
/* 102 S> */ B(LdaContextSlot), R(context), U8(4), U8(1),
B(Star), R(0),
B(LdaCurrentContextSlot), U8(4),
/* 120 E> */ B(Mul), R(0), U8(2),
/* 130 S> */ B(Return),
]
constant pool: [

View File

@ -96,7 +96,7 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 23
bytecode array length: 22
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(Wide), B(LdaSmi), U16(1234),
@ -105,8 +105,8 @@ bytecodes: [
/* 66 E> */ B(Mul), R(0), U8(2),
B(Star), R(2),
B(SubSmi), U8(1), R(2), U8(3),
B(LdrUndefined), R(1),
B(Ldar), R(1),
B(LdaUndefined),
B(Star), R(1),
/* 74 S> */ B(Nop),
/* 84 S> */ B(Return),
]

View File

@ -54,7 +54,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.LoadLiteral(factory->NewStringFromStaticChars("A constant"))
.StoreAccumulatorInRegister(reg)
.LoadUndefined()
.Debugger() // Prevent peephole optimization LdaNull, Star -> LdrNull.
.StoreAccumulatorInRegister(reg)
.LoadNull()
.StoreAccumulatorInRegister(reg)
.LoadTheHole()
@ -308,17 +308,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreLookupSlot(wide_name, LanguageMode::SLOPPY)
.StoreLookupSlot(wide_name, LanguageMode::STRICT);
// Emit loads which will be transformed to Ldr equivalents by the peephole
// optimizer.
builder.LoadContextSlot(reg, 1, 0)
.StoreAccumulatorInRegister(reg)
.LoadContextSlot(Register::current_context(), 1, 0)
.StoreAccumulatorInRegister(reg)
.LoadGlobal(0, TypeofMode::NOT_INSIDE_TYPEOF)
.StoreAccumulatorInRegister(reg)
.LoadUndefined()
.StoreAccumulatorInRegister(reg);
// CreateClosureWide
builder.CreateClosure(1000, NOT_TENURED);
@ -392,10 +381,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
if (!FLAG_ignition_peephole) {
// Insert entries for bytecodes only emitted by peephole optimizer.
scorecard[Bytecodes::ToByte(Bytecode::kLdrGlobal)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kLdrContextSlot)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kLdrCurrentContextSlot)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kLdrUndefined)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kLogicalNot)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kJump)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kJumpIfTrue)] = 1;

View File

@ -321,81 +321,6 @@ TEST_F(BytecodePeepholeOptimizerTest, NopStatementStackCheck) {
// Tests covering BytecodePeepholeOptimizer::UpdateLastAndCurrentBytecodes().
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaGlobalStar) {
const uint32_t operands[] = {19191,
static_cast<uint32_t>(Register(1).ToOperand())};
const int expected_operand_count = static_cast<int>(arraysize(operands));
BytecodeNode first(Bytecode::kLdaGlobal, operands[0]);
BytecodeNode second(Bytecode::kStar, operands[1]);
BytecodeNode third(Bytecode::kReturn);
optimizer()->Write(&first);
optimizer()->Write(&second);
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdrGlobal);
CHECK_EQ(last_written().operand_count(), expected_operand_count);
for (int i = 0; i < expected_operand_count; ++i) {
CHECK_EQ(last_written().operand(i), operands[i]);
}
optimizer()->Write(&third);
CHECK_EQ(write_count(), 2);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdar);
CHECK_EQ(last_written().operand(0), operands[expected_operand_count - 1]);
Flush();
CHECK_EQ(last_written().bytecode(), third.bytecode());
}
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaContextSlotStar) {
const uint32_t operands[] = {
static_cast<uint32_t>(Register(200000).ToOperand()), 55005500,
static_cast<uint32_t>(Register(0).ToOperand()),
static_cast<uint32_t>(Register(1).ToOperand())};
const int expected_operand_count = static_cast<int>(arraysize(operands));
BytecodeNode first(Bytecode::kLdaContextSlot, operands[0], operands[1],
operands[2]);
BytecodeNode second(Bytecode::kStar, operands[3]);
BytecodeNode third(Bytecode::kReturn);
optimizer()->Write(&first);
optimizer()->Write(&second);
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdrContextSlot);
CHECK_EQ(last_written().operand_count(), expected_operand_count);
for (int i = 0; i < expected_operand_count; ++i) {
CHECK_EQ(last_written().operand(i), operands[i]);
}
optimizer()->Write(&third);
CHECK_EQ(write_count(), 2);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdar);
CHECK_EQ(last_written().operand(0), operands[expected_operand_count - 1]);
Flush();
CHECK_EQ(last_written().bytecode(), third.bytecode());
}
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaUndefinedStar) {
const uint32_t operands[] = {
static_cast<uint32_t>(Register(100000).ToOperand())};
const int expected_operand_count = static_cast<int>(arraysize(operands));
BytecodeNode first(Bytecode::kLdaUndefined);
BytecodeNode second(Bytecode::kStar, operands[0]);
BytecodeNode third(Bytecode::kReturn);
optimizer()->Write(&first);
optimizer()->Write(&second);
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdrUndefined);
CHECK_EQ(last_written().operand_count(), expected_operand_count);
for (int i = 0; i < expected_operand_count; ++i) {
CHECK_EQ(last_written().operand(i), operands[i]);
}
optimizer()->Write(&third);
CHECK_EQ(write_count(), 2);
CHECK_EQ(last_written().bytecode(), Bytecode::kLdar);
CHECK_EQ(last_written().operand(0), operands[expected_operand_count - 1]);
Flush();
CHECK_EQ(last_written().bytecode(), third.bytecode());
}
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaSmiWithBinaryOp) {
Bytecode operator_replacement_pairs[][2] = {
{Bytecode::kAdd, Bytecode::kAddSmi},