[ignition] Introduce Switch bytecode for generators

Introduce a new SwitchSmiTable bytecode for generators, which does a
table lookup for the accumulator value in a jump table stored in the
constant array pool. This removes the if-else chains at resumable
function/loop headers.

As a drive-by, add a scoped environment saving struct to the bytecode
graph builder.

Bug: v8:6351
Bug: v8:6366
Change-Id: I63be15a8b599d6684c7df19dedb8860562678fb0
Reviewed-on: https://chromium-review.googlesource.com/500271
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45314}
This commit is contained in:
Leszek Swirski 2017-05-15 17:31:05 +01:00 committed by Commit Bot
parent ae4216160d
commit f133bc8ad5
31 changed files with 1279 additions and 880 deletions

View File

@ -1649,6 +1649,7 @@ v8_source_set("v8_base") {
"src/interpreter/bytecode-flags.h",
"src/interpreter/bytecode-generator.cc",
"src/interpreter/bytecode-generator.h",
"src/interpreter/bytecode-jump-table.h",
"src/interpreter/bytecode-label.cc",
"src/interpreter/bytecode-label.h",
"src/interpreter/bytecode-node.cc",

View File

@ -2663,6 +2663,14 @@ class FunctionLiteral final : public Expression {
bool AllowsLazyCompilation();
bool CanSuspend() {
if (suspend_count() > 0) {
DCHECK(IsResumableFunction(kind()));
return true;
}
return false;
}
Handle<String> debug_name() const {
if (raw_name_ != NULL && !raw_name_->IsEmpty()) {
return raw_name_->string();

View File

@ -188,6 +188,10 @@ void UpdateOutLiveness(Bytecode bytecode, BytecodeLivenessState& out_liveness,
if (Bytecodes::IsForwardJump(bytecode)) {
int target_offset = accessor.GetJumpTargetOffset();
out_liveness.Union(*liveness_map.GetInLiveness(target_offset));
} else if (Bytecodes::IsSwitch(bytecode)) {
for (const auto& entry : accessor.GetJumpTableTargetOffsets()) {
out_liveness.Union(*liveness_map.GetInLiveness(entry.target_offset));
}
}
// Update from next bytecode (unless there isn't one or this is an

View File

@ -108,6 +108,18 @@ class BytecodeGraphBuilder::Environment : public ZoneObject {
int accumulator_base_;
};
// A helper for creating a temporary sub-environment for simple branches.
struct BytecodeGraphBuilder::SubEnvironment final {
public:
explicit SubEnvironment(BytecodeGraphBuilder* builder)
: builder_(builder), parent_(builder->environment()->Copy()) {}
~SubEnvironment() { builder_->set_environment(parent_); }
private:
BytecodeGraphBuilder* builder_;
BytecodeGraphBuilder::Environment* parent_;
};
// Issues:
// - Scopes - intimately tied to AST. Need to eval what is needed.
@ -870,9 +882,10 @@ BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions(
jsgraph()->TheHoleConstant());
NewBranch(check_no_extension);
Environment* true_environment = environment()->Copy();
{
SubEnvironment sub_environment(this);
NewIfFalse();
// If there is an extension, merge into the slow path.
if (slow_environment == nullptr) {
@ -883,12 +896,9 @@ BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions(
}
}
{
set_environment(true_environment);
NewIfTrue();
// Do nothing on if there is no extension, eventually falling through to
// the fast path.
}
NewIfTrue();
// Do nothing on if there is no extension, eventually falling through to
// the fast path.
}
// The depth can be zero, in which case no slow-path checks are built, and the
@ -2155,6 +2165,26 @@ void BytecodeGraphBuilder::VisitJumpIfNotUndefinedConstant() {
void BytecodeGraphBuilder::VisitJumpLoop() { BuildJump(); }
void BytecodeGraphBuilder::VisitSwitchOnSmiNoFeedback() {
PrepareEagerCheckpoint();
Node* acc = environment()->LookupAccumulator();
for (const auto& entry : bytecode_iterator().GetJumpTableTargetOffsets()) {
// TODO(leszeks): This should be a switch, but under OSR we fail to type the
// input correctly so we have to do a JS strict equal instead.
NewBranch(
NewNode(javascript()->StrictEqual(CompareOperationHint::kSignedSmall),
acc, jsgraph()->SmiConstant(entry.case_value)));
{
SubEnvironment sub_environment(this);
NewIfTrue();
MergeIntoSuccessorEnvironment(entry.target_offset);
}
NewIfFalse();
}
}
void BytecodeGraphBuilder::VisitStackCheck() {
PrepareEagerCheckpoint();
Node* node = NewNode(javascript()->StackCheck());
@ -2400,19 +2430,21 @@ void BytecodeGraphBuilder::BuildJump() {
void BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
NewBranch(condition);
Environment* if_false_environment = environment()->Copy();
NewIfTrue();
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
set_environment(if_false_environment);
{
SubEnvironment sub_environment(this);
NewIfTrue();
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
}
NewIfFalse();
}
void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) {
NewBranch(condition);
Environment* if_true_environment = environment()->Copy();
NewIfFalse();
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
set_environment(if_true_environment);
{
SubEnvironment sub_environment(this);
NewIfFalse();
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
}
NewIfTrue();
}
@ -2432,24 +2464,26 @@ void BytecodeGraphBuilder::BuildJumpIfNotEqual(Node* comperand) {
void BytecodeGraphBuilder::BuildJumpIfFalse() {
NewBranch(environment()->LookupAccumulator());
Environment* if_true_environment = environment()->Copy();
environment()->BindAccumulator(jsgraph()->FalseConstant());
NewIfFalse();
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
if_true_environment->BindAccumulator(jsgraph()->TrueConstant());
set_environment(if_true_environment);
{
SubEnvironment sub_environment(this);
NewIfFalse();
environment()->BindAccumulator(jsgraph()->FalseConstant());
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
}
NewIfTrue();
environment()->BindAccumulator(jsgraph()->TrueConstant());
}
void BytecodeGraphBuilder::BuildJumpIfTrue() {
NewBranch(environment()->LookupAccumulator());
Environment* if_false_environment = environment()->Copy();
environment()->BindAccumulator(jsgraph()->TrueConstant());
NewIfTrue();
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
if_false_environment->BindAccumulator(jsgraph()->FalseConstant());
set_environment(if_false_environment);
{
SubEnvironment sub_environment(this);
NewIfTrue();
environment()->BindAccumulator(jsgraph()->TrueConstant());
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
}
NewIfFalse();
environment()->BindAccumulator(jsgraph()->FalseConstant());
}
void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {

View File

@ -39,6 +39,7 @@ class BytecodeGraphBuilder {
private:
class Environment;
struct SubEnvironment;
void VisitBytecodes(bool stack_check);

View File

@ -2835,6 +2835,8 @@ class RepresentationSelector {
case IrOpcode::kIfException:
case IrOpcode::kIfTrue:
case IrOpcode::kIfFalse:
case IrOpcode::kIfValue:
case IrOpcode::kIfDefault:
case IrOpcode::kDeoptimize:
case IrOpcode::kEffectPhi:
case IrOpcode::kTerminate:

View File

@ -168,11 +168,14 @@ Runtime::FunctionId BytecodeArrayAccessor::GetIntrinsicIdOperand(
static_cast<IntrinsicsHelper::IntrinsicId>(raw_id));
}
Handle<Object> BytecodeArrayAccessor::GetConstantAtIndex(int index) const {
return FixedArray::get(bytecode_array()->constant_pool(), index,
bytecode_array()->GetIsolate());
}
Handle<Object> BytecodeArrayAccessor::GetConstantForIndexOperand(
int operand_index) const {
return FixedArray::get(bytecode_array()->constant_pool(),
GetIndexOperand(operand_index),
bytecode_array()->GetIsolate());
return GetConstantAtIndex(GetIndexOperand(operand_index));
}
int BytecodeArrayAccessor::GetJumpTargetOffset() const {
@ -182,16 +185,31 @@ int BytecodeArrayAccessor::GetJumpTargetOffset() const {
if (bytecode == Bytecode::kJumpLoop) {
relative_offset = -relative_offset;
}
return current_offset() + relative_offset + current_prefix_offset();
return GetAbsoluteOffset(relative_offset);
} else if (interpreter::Bytecodes::IsJumpConstant(bytecode)) {
Smi* smi = Smi::cast(*GetConstantForIndexOperand(0));
return current_offset() + smi->value() + current_prefix_offset();
return GetAbsoluteOffset(smi->value());
} else {
UNREACHABLE();
return kMinInt;
}
}
JumpTableTargetOffsets BytecodeArrayAccessor::GetJumpTableTargetOffsets()
const {
DCHECK_EQ(current_bytecode(), Bytecode::kSwitchOnSmiNoFeedback);
uint32_t table_start = GetIndexOperand(0);
uint32_t table_size = GetUnsignedImmediateOperand(1);
int32_t case_value_base = GetImmediateOperand(2);
return JumpTableTargetOffsets(this, table_start, table_size, case_value_base);
}
int BytecodeArrayAccessor::GetAbsoluteOffset(int relative_offset) const {
return current_offset() + relative_offset + current_prefix_offset();
}
bool BytecodeArrayAccessor::OffsetWithinBytecode(int offset) const {
return current_offset() <= offset &&
offset < current_offset() + current_bytecode_size();
@ -203,6 +221,68 @@ std::ostream& BytecodeArrayAccessor::PrintTo(std::ostream& os) const {
bytecode_array()->parameter_count());
}
JumpTableTargetOffsets::JumpTableTargetOffsets(
const BytecodeArrayAccessor* accessor, int table_start, int table_size,
int case_value_base)
: accessor_(accessor),
table_start_(table_start),
table_size_(table_size),
case_value_base_(case_value_base) {}
JumpTableTargetOffsets::iterator JumpTableTargetOffsets::begin() const {
return iterator(case_value_base_, table_start_, table_start_ + table_size_,
accessor_);
}
JumpTableTargetOffsets::iterator JumpTableTargetOffsets::end() const {
return iterator(case_value_base_ + table_size_, table_start_ + table_size_,
table_start_ + table_size_, accessor_);
}
JumpTableTargetOffsets::iterator::iterator(
int case_value, int table_offset, int table_end,
const BytecodeArrayAccessor* accessor)
: accessor_(accessor),
index_(case_value),
table_offset_(table_offset),
table_end_(table_end) {
UpdateAndAdvanceToValid();
}
JumpTableTargetOffset JumpTableTargetOffsets::iterator::operator*() {
DCHECK_LT(table_offset_, table_end_);
DCHECK(current_->IsSmi());
return {index_, accessor_->GetAbsoluteOffset(Smi::cast(*current_)->value())};
}
JumpTableTargetOffsets::iterator& JumpTableTargetOffsets::iterator::
operator++() {
DCHECK_LT(table_offset_, table_end_);
++table_offset_;
++index_;
UpdateAndAdvanceToValid();
return *this;
}
bool JumpTableTargetOffsets::iterator::operator!=(
const JumpTableTargetOffsets::iterator& other) {
DCHECK_EQ(accessor_, other.accessor_);
DCHECK_EQ(table_end_, other.table_end_);
DCHECK_EQ(index_ - other.index_, table_offset_ - other.table_offset_);
return index_ != other.index_;
}
void JumpTableTargetOffsets::iterator::UpdateAndAdvanceToValid() {
if (table_offset_ >= table_end_) return;
current_ = accessor_->GetConstantAtIndex(table_offset_);
Isolate* isolate = accessor_->bytecode_array()->GetIsolate();
while (current_->IsTheHole(isolate)) {
++table_offset_;
++index_;
current_ = accessor_->GetConstantAtIndex(table_offset_);
}
}
} // namespace interpreter
} // namespace internal
} // namespace v8

View File

@ -16,6 +16,48 @@ namespace v8 {
namespace internal {
namespace interpreter {
class BytecodeArrayAccessor;
struct JumpTableTargetOffset {
int case_value;
int target_offset;
};
class JumpTableTargetOffsets final {
public:
// Minimal iterator implementation for use in ranged-for.
class iterator final {
public:
iterator(int case_value, int table_offset, int table_end,
const BytecodeArrayAccessor* accessor);
JumpTableTargetOffset operator*();
iterator& operator++();
bool operator!=(const iterator& other);
private:
void UpdateAndAdvanceToValid();
const BytecodeArrayAccessor* accessor_;
Handle<Object> current_;
int index_;
int table_offset_;
int table_end_;
};
JumpTableTargetOffsets(const BytecodeArrayAccessor* accessor, int table_start,
int table_size, int case_value_base);
iterator begin() const;
iterator end() const;
private:
const BytecodeArrayAccessor* accessor_;
int table_start_;
int table_size_;
int case_value_base_;
};
class V8_EXPORT_PRIVATE BytecodeArrayAccessor {
public:
BytecodeArrayAccessor(Handle<BytecodeArray> bytecode_array,
@ -41,12 +83,21 @@ class V8_EXPORT_PRIVATE BytecodeArrayAccessor {
int GetRegisterOperandRange(int operand_index) const;
Runtime::FunctionId GetRuntimeIdOperand(int operand_index) const;
Runtime::FunctionId GetIntrinsicIdOperand(int operand_index) const;
Handle<Object> GetConstantAtIndex(int offset) const;
Handle<Object> GetConstantForIndexOperand(int operand_index) const;
// Returns the absolute offset of the branch target at the current
// bytecode. It is an error to call this method if the bytecode is
// not for a jump or conditional jump.
// Returns the absolute offset of the branch target at the current bytecode.
// It is an error to call this method if the bytecode is not for a jump or
// conditional jump.
int GetJumpTargetOffset() const;
// Returns an iterator over the absolute offsets of the targets of the current
// switch bytecode's jump table. It is an error to call this method if the
// bytecode is not a switch.
JumpTableTargetOffsets GetJumpTableTargetOffsets() const;
// Returns the absolute offset of the bytecode at the given relative offset
// from the current bytecode.
int GetAbsoluteOffset(int relative_offset) const;
bool OffsetWithinBytecode(int offset) const;

View File

@ -6,6 +6,7 @@
#include "src/globals.h"
#include "src/interpreter/bytecode-array-writer.h"
#include "src/interpreter/bytecode-jump-table.h"
#include "src/interpreter/bytecode-label.h"
#include "src/interpreter/bytecode-node.h"
#include "src/interpreter/bytecode-register-optimizer.h"
@ -162,6 +163,12 @@ void BytecodeArrayBuilder::WriteJump(BytecodeNode* node, BytecodeLabel* label) {
bytecode_array_writer_.WriteJump(node, label);
}
void BytecodeArrayBuilder::WriteSwitch(BytecodeNode* node,
BytecodeJumpTable* jump_table) {
AttachOrEmitDeferredSourceInfo(node);
bytecode_array_writer_.WriteSwitch(node, jump_table);
}
void BytecodeArrayBuilder::OutputLdarRaw(Register reg) {
uint32_t operand = static_cast<uint32_t>(reg.ToOperand());
BytecodeNode node(BytecodeNode::Ldar(BytecodeSourceInfo(), operand));
@ -295,8 +302,9 @@ class BytecodeNodeBuilder {
public:
template <typename... Operands>
INLINE(static BytecodeNode Make(BytecodeArrayBuilder* builder,
BytecodeSourceInfo source_info,
Operands... operands)) {
static_assert(sizeof...(Operands) <= Bytecodes::kMaxOperands,
"too many operands for bytecode");
builder->PrepareToOutputBytecode<bytecode, accumulator_use>();
// The "OperandHelper<operand_types>::Convert(builder, operands)..." will
// expand both the OperandType... and Operands... parameter packs e.g. for:
@ -306,37 +314,45 @@ class BytecodeNodeBuilder {
// OperandHelper<OperandType::kReg>::Convert(builder, reg),
// OperandHelper<OperandType::kImm>::Convert(builder, immediate),
return BytecodeNode::Create<bytecode, accumulator_use, operand_types...>(
source_info,
builder->CurrentSourcePosition(bytecode),
OperandHelper<operand_types>::Convert(builder, operands)...);
}
};
#define DEFINE_BYTECODE_OUTPUT(name, ...) \
template <typename... Operands> \
void BytecodeArrayBuilder::Output##name(Operands... operands) { \
static_assert(sizeof...(Operands) <= Bytecodes::kMaxOperands, \
"too many operands for bytecode"); \
BytecodeNode node( \
BytecodeNodeBuilder<Bytecode::k##name, __VA_ARGS__>::Make< \
Operands...>(this, CurrentSourcePosition(Bytecode::k##name), \
operands...)); \
Write(&node); \
} \
\
template <typename... Operands> \
void BytecodeArrayBuilder::Output##name(BytecodeLabel* label, \
Operands... operands) { \
DCHECK(Bytecodes::IsJump(Bytecode::k##name)); \
BytecodeNode node( \
BytecodeNodeBuilder<Bytecode::k##name, __VA_ARGS__>::Make< \
Operands...>(this, CurrentSourcePosition(Bytecode::k##name), \
operands...)); \
WriteJump(&node, label); \
LeaveBasicBlock(); \
#define DEFINE_BYTECODE_OUTPUT(name, ...) \
template <typename... Operands> \
BytecodeNode BytecodeArrayBuilder::Create##name##Node( \
Operands... operands) { \
return BytecodeNodeBuilder<Bytecode::k##name, __VA_ARGS__>::Make( \
this, operands...); \
} \
\
template <typename... Operands> \
void BytecodeArrayBuilder::Output##name(Operands... operands) { \
BytecodeNode node(Create##name##Node(operands...)); \
Write(&node); \
} \
\
template <typename... Operands> \
void BytecodeArrayBuilder::Output##name(BytecodeLabel* label, \
Operands... operands) { \
DCHECK(Bytecodes::IsJump(Bytecode::k##name)); \
BytecodeNode node(Create##name##Node(operands...)); \
WriteJump(&node, label); \
LeaveBasicBlock(); \
}
BYTECODE_LIST(DEFINE_BYTECODE_OUTPUT)
#undef DEFINE_BYTECODE_OUTPUT
void BytecodeArrayBuilder::OutputSwitchOnSmiNoFeedback(
BytecodeJumpTable* jump_table) {
BytecodeNode node(CreateSwitchOnSmiNoFeedbackNode(
jump_table->constant_pool_index(), jump_table->size(),
jump_table->case_value_base()));
WriteSwitch(&node, jump_table);
LeaveBasicBlock();
}
BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
Register reg,
int feedback_slot) {
@ -1008,6 +1024,16 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeJumpTable* jump_table,
int case_value) {
// Flush the register optimizer when binding a jump table entry to ensure
// all expected registers are valid when jumping to this location.
if (register_optimizer_) register_optimizer_->Flush();
bytecode_array_writer_.BindJumpTableEntry(jump_table, case_value);
LeaveBasicBlock();
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
DCHECK(!label->is_bound());
OutputJump(label, 0);
@ -1122,6 +1148,12 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label,
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::SwitchOnSmiNoFeedback(
BytecodeJumpTable* jump_table) {
OutputSwitchOnSmiNoFeedback(jump_table);
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
if (position != kNoSourcePosition) {
// We need to attach a non-breakable source position to a stack
@ -1387,6 +1419,16 @@ size_t BytecodeArrayBuilder::GetConstantPoolEntry(const Scope* scope) {
SINGLETON_CONSTANT_ENTRY_TYPES(ENTRY_GETTER)
#undef ENTRY_GETTER
BytecodeJumpTable* BytecodeArrayBuilder::AllocateJumpTable(
int size, int case_value_base) {
DCHECK_GT(size, 0);
size_t constant_pool_index = constant_array_builder()->InsertJumpTable(size);
return new (zone())
BytecodeJumpTable(constant_pool_index, size, case_value_base, zone());
}
size_t BytecodeArrayBuilder::AllocateDeferredConstantPoolEntry() {
return constant_array_builder()->InsertDeferred();
}

View File

@ -28,6 +28,7 @@ namespace interpreter {
class BytecodeLabel;
class BytecodeNode;
class BytecodeRegisterOptimizer;
class BytecodeJumpTable;
class Register;
class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
@ -359,6 +360,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
// Flow Control.
BytecodeArrayBuilder& Bind(BytecodeLabel* label);
BytecodeArrayBuilder& Bind(const BytecodeLabel& target, BytecodeLabel* label);
BytecodeArrayBuilder& Bind(BytecodeJumpTable* jump_table, int case_value);
BytecodeArrayBuilder& Jump(BytecodeLabel* label);
BytecodeArrayBuilder& JumpLoop(BytecodeLabel* label, int loop_depth);
@ -376,6 +378,8 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
BytecodeArrayBuilder& JumpIfNotNil(BytecodeLabel* label, Token::Value op,
NilValue nil);
BytecodeArrayBuilder& SwitchOnSmiNoFeedback(BytecodeJumpTable* jump_table);
BytecodeArrayBuilder& StackCheck(int position);
// Sets the pending message to the value in the accumulator, and returns the
@ -413,6 +417,10 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
// entry, so that it can be referenced by above exception handling support.
int NewHandlerEntry() { return handler_table_builder()->NewHandlerEntry(); }
// Allocates a new jump table of given |size| and |case_value_base| in the
// constant pool.
BytecodeJumpTable* AllocateJumpTable(int size, int case_value_base);
// Gets a constant pool entry.
size_t GetConstantPoolEntry(const AstRawString* raw_string);
size_t GetConstantPoolEntry(const AstValue* heap_number);
@ -483,14 +491,18 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
// Returns the current source position for the given |bytecode|.
INLINE(BytecodeSourceInfo CurrentSourcePosition(Bytecode bytecode));
#define DECLARE_BYTECODE_OUTPUT(Name, ...) \
template <typename... Operands> \
INLINE(void Output##Name(Operands... operands)); \
template <typename... Operands> \
#define DECLARE_BYTECODE_OUTPUT(Name, ...) \
template <typename... Operands> \
INLINE(BytecodeNode Create##Name##Node(Operands... operands)); \
template <typename... Operands> \
INLINE(void Output##Name(Operands... operands)); \
template <typename... Operands> \
INLINE(void Output##Name(BytecodeLabel* label, Operands... operands));
BYTECODE_LIST(DECLARE_BYTECODE_OUTPUT)
#undef DECLARE_OPERAND_TYPE_INFO
INLINE(void OutputSwitchOnSmiNoFeedback(BytecodeJumpTable* jump_table));
bool RegisterIsValid(Register reg) const;
bool RegisterListIsValid(RegisterList reg_list) const;
@ -507,6 +519,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
// Write bytecode to bytecode array.
void Write(BytecodeNode* node);
void WriteJump(BytecodeNode* node, BytecodeLabel* label);
void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* label);
// Not implemented as the illegal bytecode is used inside internally
// to indicate a bytecode field is not valid or an error has occured

View File

@ -5,6 +5,7 @@
#include "src/interpreter/bytecode-array-writer.h"
#include "src/api.h"
#include "src/interpreter/bytecode-jump-table.h"
#include "src/interpreter/bytecode-label.h"
#include "src/interpreter/bytecode-node.h"
#include "src/interpreter/bytecode-register.h"
@ -79,6 +80,20 @@ void BytecodeArrayWriter::WriteJump(BytecodeNode* node, BytecodeLabel* label) {
EmitJump(node, label);
}
void BytecodeArrayWriter::WriteSwitch(BytecodeNode* node,
BytecodeJumpTable* jump_table) {
DCHECK(Bytecodes::IsSwitch(node->bytecode()));
// TODO(rmcilroy): For jump tables we could also mark the table as dead,
// thereby avoiding emitting dead code when we bind the entries.
if (exit_seen_in_block_) return; // Don't emit dead code.
UpdateExitSeenInBlock(node->bytecode());
MaybeElideLastBytecode(node->bytecode(), node->source_info().is_valid());
UpdateSourcePositionTable(node);
EmitSwitch(node, jump_table);
}
void BytecodeArrayWriter::BindLabel(BytecodeLabel* label) {
size_t current_offset = bytecodes()->size();
if (label->is_forward_target()) {
@ -106,6 +121,22 @@ void BytecodeArrayWriter::BindLabel(const BytecodeLabel& target,
// changed here.
}
void BytecodeArrayWriter::BindJumpTableEntry(BytecodeJumpTable* jump_table,
int case_value) {
DCHECK(!jump_table->is_bound(case_value));
size_t current_offset = bytecodes()->size();
size_t relative_jump = current_offset - jump_table->switch_bytecode_offset();
constant_array_builder()->SetJumpTableSmi(
jump_table->ConstantPoolEntryFor(case_value),
Smi::FromInt(static_cast<int>(relative_jump)));
jump_table->mark_bound(case_value);
InvalidateLastBytecode();
exit_seen_in_block_ = false; // Starting a new basic block.
}
void BytecodeArrayWriter::UpdateSourcePositionTable(
const BytecodeNode* const node) {
int bytecode_offset = static_cast<int>(bytecodes()->size());
@ -387,6 +418,16 @@ void BytecodeArrayWriter::EmitJump(BytecodeNode* node, BytecodeLabel* label) {
EmitBytecode(node);
}
void BytecodeArrayWriter::EmitSwitch(BytecodeNode* node,
BytecodeJumpTable* jump_table) {
DCHECK(Bytecodes::IsSwitch(node->bytecode()));
size_t current_offset = bytecodes()->size();
jump_table->set_switch_bytecode_offset(current_offset);
EmitBytecode(node);
}
} // namespace interpreter
} // namespace internal
} // namespace v8

View File

@ -19,6 +19,7 @@ namespace interpreter {
class BytecodeLabel;
class BytecodeNode;
class BytecodeJumpTable;
class ConstantArrayBuilder;
// Class for emitting bytecode as the final stage of the bytecode
@ -31,8 +32,10 @@ class V8_EXPORT_PRIVATE BytecodeArrayWriter final {
void Write(BytecodeNode* node);
void WriteJump(BytecodeNode* node, BytecodeLabel* label);
void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table);
void BindLabel(BytecodeLabel* label);
void BindLabel(const BytecodeLabel& target, BytecodeLabel* label);
void BindJumpTableEntry(BytecodeJumpTable* jump_table, int case_value);
Handle<BytecodeArray> ToBytecodeArray(Isolate* isolate, int register_count,
int parameter_count,
Handle<FixedArray> handler_table);
@ -61,6 +64,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayWriter final {
void EmitBytecode(const BytecodeNode* const node);
void EmitJump(BytecodeNode* node, BytecodeLabel* label);
void EmitSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table);
void UpdateSourcePositionTable(const BytecodeNode* const node);
void UpdateExitSeenInBlock(Bytecode bytecode);

View File

@ -11,6 +11,7 @@
#include "src/compilation-info.h"
#include "src/compiler.h"
#include "src/interpreter/bytecode-flags.h"
#include "src/interpreter/bytecode-jump-table.h"
#include "src/interpreter/bytecode-label.h"
#include "src/interpreter/bytecode-register-allocator.h"
#include "src/interpreter/control-flow-builders.h"
@ -648,7 +649,7 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
execution_control_(nullptr),
execution_context_(nullptr),
execution_result_(nullptr),
generator_resume_points_(info->literal()->suspend_count(), info->zone()),
generator_jump_table_(nullptr),
generator_state_(),
loop_depth_(0) {
DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope());
@ -728,9 +729,8 @@ void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) {
RegisterAllocationScope register_scope(this);
if (IsResumableFunction(info()->literal()->kind())) {
generator_state_ = register_allocator()->NewRegister();
VisitGeneratorPrologue();
if (info()->literal()->CanSuspend()) {
BuildGeneratorPrologue();
}
if (closure_scope()->NeedsContext()) {
@ -743,14 +743,6 @@ void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) {
GenerateBytecodeBody();
}
// In generator functions, we may not have visited every yield in the AST
// since we skip some obviously dead code. Hence the generated bytecode may
// contain jumps to unbound labels (resume points that will never be used).
// We bind these now.
for (auto& label : generator_resume_points_) {
if (!label.is_bound()) builder()->Bind(&label);
}
// Emit an implicit return instruction in case control flow can fall off the
// end of the function without an explicit return being present on all paths.
if (builder()->RequiresImplicitReturn()) {
@ -776,7 +768,7 @@ void BytecodeGenerator::GenerateBytecodeBody() {
// Create a generator object if necessary and initialize the
// {.generator_object} variable.
if (IsResumableFunction(info()->literal()->kind())) {
if (info()->literal()->CanSuspend()) {
BuildGeneratorObjectVariableInitialization();
}
@ -806,20 +798,6 @@ void BytecodeGenerator::GenerateBytecodeBody() {
VisitStatements(info()->literal()->body());
}
void BytecodeGenerator::BuildIndexedJump(Register index, size_t start_index,
size_t size,
ZoneVector<BytecodeLabel>& targets) {
// TODO(neis): Optimize this by using a proper jump table.
DCHECK_LE(start_index + size, targets.size());
for (size_t i = start_index; i < start_index + size; i++) {
builder()
->LoadLiteral(Smi::FromInt(static_cast<int>(i)))
.CompareOperation(Token::Value::EQ_STRICT, index)
.JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &(targets[i]));
}
BuildAbort(BailoutReason::kInvalidJumpTableIndex);
}
void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt,
LoopBuilder* loop_builder) {
// Recall that stmt->yield_count() is always zero inside ordinary
@ -827,36 +805,39 @@ void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt,
if (stmt->suspend_count() == 0) {
loop_builder->LoopHeader();
} else {
// Collect all labels for generator resume points within the loop (if any)
// so that they can be bound to the loop header below. Also create fresh
// labels for these resume points, to be used inside the loop.
ZoneVector<BytecodeLabel> resume_points_in_loop(zone());
size_t first_yield = stmt->first_suspend_id();
DCHECK_LE(first_yield + stmt->suspend_count(),
generator_resume_points_.size());
for (size_t id = first_yield; id < first_yield + stmt->suspend_count();
id++) {
auto& label = generator_resume_points_[id];
resume_points_in_loop.push_back(label);
generator_resume_points_[id] = BytecodeLabel();
}
loop_builder->LoopHeaderInGenerator(
&generator_jump_table_, static_cast<int>(stmt->first_suspend_id()),
static_cast<int>(stmt->suspend_count()));
loop_builder->LoopHeader(&resume_points_in_loop);
// Perform state dispatch on the generator state, assuming this is a resume.
builder()
->LoadAccumulatorWithRegister(generator_state_)
.SwitchOnSmiNoFeedback(generator_jump_table_);
// If we are not resuming, fall through to loop body.
// If we are resuming, perform state dispatch.
// We fall through when the generator state is not in the jump table. If we
// are not resuming, we want to fall through to the loop body.
// TODO(leszeks): Only generate this test for debug builds, we can skip it
// entirely in release assuming that the generator states is always valid.
BytecodeLabel not_resuming;
builder()
->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
.CompareOperation(Token::Value::EQ_STRICT, generator_state_)
.JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &not_resuming);
BuildIndexedJump(generator_state_, first_yield, stmt->suspend_count(),
generator_resume_points_);
// Otherwise this is an error.
BuildAbort(BailoutReason::kInvalidJumpTableIndex);
builder()->Bind(&not_resuming);
}
}
void BytecodeGenerator::VisitGeneratorPrologue() {
void BytecodeGenerator::BuildGeneratorPrologue() {
DCHECK_GT(info()->literal()->suspend_count(), 0);
generator_state_ = register_allocator()->NewRegister();
generator_jump_table_ =
builder()->AllocateJumpTable(info()->literal()->suspend_count(), 0);
// The generator resume trampoline abuses the new.target register both to
// indicate that this is a resume call and to pass in the generator object.
// In ordinary calls, new.target is always undefined because generator
@ -867,24 +848,27 @@ void BytecodeGenerator::VisitGeneratorPrologue() {
->LoadAccumulatorWithRegister(generator_object)
.JumpIfUndefined(&regular_call);
// This is a resume call. Restore the current context and the registers, then
// perform state dispatch.
Register dummy = register_allocator()->NewRegister();
// This is a resume call. Restore the current context and the registers,
// then perform state dispatch.
Register generator_context = register_allocator()->NewRegister();
builder()
->CallRuntime(Runtime::kInlineGeneratorGetContext, generator_object)
.PushContext(dummy)
.PushContext(generator_context)
.ResumeGenerator(generator_object)
.StoreAccumulatorInRegister(generator_state_);
BuildIndexedJump(generator_state_, 0, generator_resume_points_.size(),
generator_resume_points_);
.StoreAccumulatorInRegister(generator_state_)
.SwitchOnSmiNoFeedback(generator_jump_table_);
// We fall through when the generator state is not in the jump table.
// TODO(leszeks): Only generate this for debug builds.
BuildAbort(BailoutReason::kInvalidJumpTableIndex);
// This is a regular call.
builder()
->Bind(&regular_call)
.LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
.StoreAccumulatorInRegister(generator_state_);
// This is a regular call. Fall through to the ordinary function prologue,
// after which we will run into the generator object creation and other extra
// code inserted by the parser.
// Now fall through to the ordinary function prologue, after which we will run
// into the generator object creation and other extra code inserted by the
// parser.
}
void BytecodeGenerator::VisitBlock(Block* stmt) {
@ -1215,7 +1199,6 @@ void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
loop_backbranch.Bind(builder());
loop_builder.JumpToHeader(loop_depth_);
}
loop_builder.EndLoop();
}
void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
@ -1235,7 +1218,6 @@ void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
}
VisitIterationBody(stmt, &loop_builder);
loop_builder.JumpToHeader(loop_depth_);
loop_builder.EndLoop();
}
void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
@ -1263,7 +1245,6 @@ void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
Visit(stmt->next());
}
loop_builder.JumpToHeader(loop_depth_);
loop_builder.EndLoop();
}
void BytecodeGenerator::VisitForInAssignment(Expression* expr,
@ -1340,7 +1321,6 @@ void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
return;
}
LoopBuilder loop_builder(builder());
BytecodeLabel subject_null_label, subject_undefined_label;
// Prepare the state for executing ForIn.
@ -1362,20 +1342,22 @@ void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
builder()->StoreAccumulatorInRegister(index);
// The loop
VisitIterationHeader(stmt, &loop_builder);
builder()->SetExpressionAsStatementPosition(stmt->each());
builder()->ForInContinue(index, cache_length);
loop_builder.BreakIfFalse(ToBooleanMode::kAlreadyBoolean);
FeedbackSlot slot = stmt->ForInFeedbackSlot();
builder()->ForInNext(receiver, index, triple.Truncate(2),
feedback_index(slot));
loop_builder.ContinueIfUndefined();
VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
VisitIterationBody(stmt, &loop_builder);
builder()->ForInStep(index);
builder()->StoreAccumulatorInRegister(index);
loop_builder.JumpToHeader(loop_depth_);
loop_builder.EndLoop();
{
LoopBuilder loop_builder(builder());
VisitIterationHeader(stmt, &loop_builder);
builder()->SetExpressionAsStatementPosition(stmt->each());
builder()->ForInContinue(index, cache_length);
loop_builder.BreakIfFalse(ToBooleanMode::kAlreadyBoolean);
FeedbackSlot slot = stmt->ForInFeedbackSlot();
builder()->ForInNext(receiver, index, triple.Truncate(2),
feedback_index(slot));
loop_builder.ContinueIfUndefined();
VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
VisitIterationBody(stmt, &loop_builder);
builder()->ForInStep(index);
builder()->StoreAccumulatorInRegister(index);
loop_builder.JumpToHeader(loop_depth_);
}
builder()->Bind(&subject_null_label);
builder()->Bind(&subject_undefined_label);
}
@ -1395,7 +1377,6 @@ void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
VisitForEffect(stmt->assign_each());
VisitIterationBody(stmt, &loop_builder);
loop_builder.JumpToHeader(loop_depth_);
loop_builder.EndLoop();
}
void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
@ -2436,7 +2417,7 @@ void BytecodeGenerator::VisitSuspend(Suspend* expr) {
}
builder()->Return(); // Hard return (ignore any finally blocks).
builder()->Bind(&(generator_resume_points_[expr->suspend_id()]));
builder()->Bind(generator_jump_table_, static_cast<int>(expr->suspend_id()));
// Upon resume, we continue here.
{
@ -2458,6 +2439,7 @@ void BytecodeGenerator::VisitSuspend(Suspend* expr) {
? Runtime::kInlineAsyncGeneratorGetAwaitInputOrDebugPos
: Runtime::kInlineGeneratorGetInputOrDebugPos;
DCHECK(generator.is_valid());
builder()
->CallRuntime(get_generator_input, generator)
.StoreAccumulatorInRegister(input);

View File

@ -21,6 +21,7 @@ namespace interpreter {
class GlobalDeclarationsBuilder;
class LoopBuilder;
class BytecodeJumpTable;
class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
public:
@ -133,7 +134,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildNewLocalCatchContext(Scope* scope);
void BuildNewLocalWithContext(Scope* scope);
void VisitGeneratorPrologue();
void BuildGeneratorPrologue();
void VisitArgumentsObject(Variable* variable);
void VisitRestArgumentsArray(Variable* rest);
@ -239,7 +240,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
ContextScope* execution_context_;
ExpressionResultScope* execution_result_;
ZoneVector<BytecodeLabel> generator_resume_points_;
BytecodeJumpTable* generator_jump_table_;
Register generator_state_;
int loop_depth_;
};

View File

@ -0,0 +1,88 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_INTERPRETER_BYTECODE_JUMP_TABLE_H_
#define V8_INTERPRETER_BYTECODE_JUMP_TABLE_H_
#include "src/bit-vector.h"
#include "src/zone/zone.h"
namespace v8 {
namespace internal {
namespace interpreter {
class ConstantArrayBuilder;
// A jump table for a set of targets in a bytecode array. When an entry in the
// table is bound, it represents a known position in the bytecode array. If no
// entries match, the switch falls through.
class V8_EXPORT_PRIVATE BytecodeJumpTable final : public ZoneObject {
public:
// Constructs a new BytecodeJumpTable starting at |constant_pool_index|, with
// the given |size|, where the case values of the table start at
// |case_value_base|.
BytecodeJumpTable(size_t constant_pool_index, int size, int case_value_base,
Zone* zone)
:
#ifdef DEBUG
bound_(size, zone),
#endif
constant_pool_index_(constant_pool_index),
switch_bytecode_offset_(kInvalidOffset),
size_(size),
case_value_base_(case_value_base) {
}
size_t constant_pool_index() const { return constant_pool_index_; }
size_t switch_bytecode_offset() const { return switch_bytecode_offset_; }
int case_value_base() const { return case_value_base_; }
int size() const { return size_; }
#ifdef DEBUG
bool is_bound(int case_value) const {
DCHECK_GE(case_value, case_value_base_);
DCHECK_LT(case_value, case_value_base_ + size());
return bound_.Contains(case_value - case_value_base_);
}
#endif
size_t ConstantPoolEntryFor(int case_value) {
DCHECK_GE(case_value, case_value_base_);
return constant_pool_index_ + case_value - case_value_base_;
}
private:
static const size_t kInvalidIndex = static_cast<size_t>(-1);
static const size_t kInvalidOffset = static_cast<size_t>(-1);
void mark_bound(int case_value) {
#ifdef DEBUG
DCHECK_GE(case_value, case_value_base_);
DCHECK_LT(case_value, case_value_base_ + size());
bound_.Add(case_value - case_value_base_);
#endif
}
void set_switch_bytecode_offset(size_t offset) {
DCHECK_EQ(switch_bytecode_offset_, kInvalidOffset);
switch_bytecode_offset_ = offset;
}
#ifdef DEBUG
// This bit vector is only used for DCHECKS, so only store the field in debug
// builds.
BitVector bound_;
#endif
size_t constant_pool_index_;
size_t switch_bytecode_offset_;
int size_;
int case_value_base_;
friend class BytecodeArrayWriter;
};
} // namespace interpreter
} // namespace internal
} // namespace v8
#endif // V8_INTERPRETER_BYTECODE_JUMP_TABLE_H_

View File

@ -64,12 +64,14 @@ class V8_EXPORT_PRIVATE BytecodeRegisterOptimizer final
// Prepares for |bytecode|.
template <Bytecode bytecode, AccumulatorUse accumulator_use>
INLINE(void PrepareForBytecode()) {
if (Bytecodes::IsJump(bytecode) || bytecode == Bytecode::kDebugger ||
if (Bytecodes::IsJump(bytecode) || Bytecodes::IsSwitch(bytecode) ||
bytecode == Bytecode::kDebugger ||
bytecode == Bytecode::kSuspendGenerator) {
// All state must be flushed before emitting
// - a jump bytecode (as the register equivalents at the jump target
// aren't
// known.
// aren't known)
// - a switch bytecode (as the register equivalents at the switch targets
// aren't known)
// - a call to the debugger (as it can manipulate locals and parameters),
// - a generator suspend (as this involves saving all registers).
Flush();

View File

@ -284,6 +284,10 @@ namespace interpreter {
V(JumpIfJSReceiver, AccumulatorUse::kRead, OperandType::kUImm) \
V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kUImm) \
\
/* Smi-table lookup for switch statements */ \
V(SwitchOnSmiNoFeedback, AccumulatorUse::kRead, OperandType::kIdx, \
OperandType::kUImm, OperandType::kImm) \
\
/* Complex flow control For..in */ \
V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg, \
OperandType::kRegOutTriple) \
@ -611,6 +615,11 @@ class V8_EXPORT_PRIVATE Bytecodes final {
return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
}
// Returns true if the bytecode is a switch.
static constexpr bool IsSwitch(Bytecode bytecode) {
return bytecode == Bytecode::kSwitchOnSmiNoFeedback;
}
// Returns true if |bytecode| has no effects. These bytecodes only manipulate
// interpreter frame state and will never throw.
static constexpr bool IsWithoutExternalSideEffects(Bytecode bytecode) {

View File

@ -38,11 +38,13 @@ void ConstantArrayBuilder::ConstantArraySlice::Unreserve() {
}
size_t ConstantArrayBuilder::ConstantArraySlice::Allocate(
ConstantArrayBuilder::Entry entry) {
DCHECK_GT(available(), 0u);
ConstantArrayBuilder::Entry entry, size_t count) {
DCHECK_GE(available(), count);
size_t index = constants_.size();
DCHECK_LT(index, capacity());
constants_.push_back(entry);
for (size_t i = 0; i < count; ++i) {
constants_.push_back(entry);
}
return index + start_index();
}
@ -65,7 +67,12 @@ void ConstantArrayBuilder::ConstantArraySlice::CheckAllElementsAreUnique(
Isolate* isolate) const {
std::set<Object*> elements;
for (const Entry& entry : constants_) {
// TODO(leszeks): Ignore jump tables because they have to be contiguous,
// so they can contain duplicates.
if (entry.IsJumpTableEntry()) continue;
Handle<Object> handle = entry.ToHandle(isolate);
if (elements.find(*handle) != elements.end()) {
std::ostringstream os;
os << "Duplicate constant found: " << Brief(*handle) << std::endl;
@ -220,9 +227,14 @@ SINGLETON_CONSTANT_ENTRY_TYPES(INSERT_ENTRY)
ConstantArrayBuilder::index_t ConstantArrayBuilder::AllocateIndex(
ConstantArrayBuilder::Entry entry) {
return AllocateIndexArray(entry, 1);
}
ConstantArrayBuilder::index_t ConstantArrayBuilder::AllocateIndexArray(
ConstantArrayBuilder::Entry entry, size_t count) {
for (size_t i = 0; i < arraysize(idx_slice_); ++i) {
if (idx_slice_[i]->available() > 0) {
return static_cast<index_t>(idx_slice_[i]->Allocate(entry));
if (idx_slice_[i]->available() >= count) {
return static_cast<index_t>(idx_slice_[i]->Allocate(entry, count));
}
}
UNREACHABLE();
@ -254,11 +266,24 @@ size_t ConstantArrayBuilder::InsertDeferred() {
return AllocateIndex(Entry::Deferred());
}
size_t ConstantArrayBuilder::InsertJumpTable(size_t size) {
return AllocateIndexArray(Entry::UninitializedJumpTableSmi(), size);
}
void ConstantArrayBuilder::SetDeferredAt(size_t index, Handle<Object> object) {
ConstantArraySlice* slice = IndexToSlice(index);
return slice->At(index).SetDeferred(object);
}
void ConstantArrayBuilder::SetJumpTableSmi(size_t index, Smi* smi) {
ConstantArraySlice* slice = IndexToSlice(index);
// Allow others to reuse these Smis, but insert using emplace to avoid
// overwriting existing values in the Smi map (which may have a smaller
// operand size).
smi_map_.emplace(smi, static_cast<index_t>(index));
return slice->At(index).SetJumpTableSmi(smi);
}
OperandSize ConstantArrayBuilder::CreateReservedEntry() {
for (size_t i = 0; i < arraysize(idx_slice_); ++i) {
if (idx_slice_[i]->available() > 0) {
@ -311,7 +336,11 @@ Handle<Object> ConstantArrayBuilder::Entry::ToHandle(Isolate* isolate) const {
case Tag::kHandle:
return handle_;
case Tag::kSmi:
case Tag::kJumpTableSmi:
return handle(smi_, isolate);
case Tag::kUninitializedJumpTableSmi:
// TODO(leszeks): There's probably a better value we could use here.
return isolate->factory()->the_hole_value();
case Tag::kRawString:
return raw_string_->string();
case Tag::kHeapNumber:

View File

@ -70,9 +70,18 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final BASE_EMBEDDED {
// SetDeferredAt().
size_t InsertDeferred();
// Inserts |size| consecutive empty entries and returns the array index
// associated with the first reservation. Each entry's Smi value can be
// inserted by calling SetJumpTableSmi().
size_t InsertJumpTable(size_t size);
// Sets the deferred value at |index| to |object|.
void SetDeferredAt(size_t index, Handle<Object> object);
// Sets the jump table entry at |index| to |smi|. Note that |index| is the
// constant pool index, not the switch case value.
void SetJumpTableSmi(size_t index, Smi* smi);
// Creates a reserved entry in the constant pool and returns
// the size of the operand that'll be required to hold the entry
// when committed.
@ -107,14 +116,29 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final BASE_EMBEDDED {
static Entry Deferred() { return Entry(Tag::kDeferred); }
static Entry UninitializedJumpTableSmi() {
return Entry(Tag::kUninitializedJumpTableSmi);
}
bool IsDeferred() const { return tag_ == Tag::kDeferred; }
bool IsJumpTableEntry() const {
return tag_ == Tag::kUninitializedJumpTableSmi ||
tag_ == Tag::kJumpTableSmi;
}
void SetDeferred(Handle<Object> handle) {
DCHECK(tag_ == Tag::kDeferred);
tag_ = Tag::kHandle;
handle_ = handle;
}
void SetJumpTableSmi(Smi* smi) {
DCHECK(tag_ == Tag::kUninitializedJumpTableSmi);
tag_ = Tag::kJumpTableSmi;
smi_ = smi;
}
Handle<Object> ToHandle(Isolate* isolate) const;
private:
@ -135,6 +159,8 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final BASE_EMBEDDED {
kRawString,
kHeapNumber,
kScope,
kUninitializedJumpTableSmi,
kJumpTableSmi,
#define ENTRY_TAG(NAME, ...) k##NAME,
SINGLETON_CONSTANT_ENTRY_TYPES(ENTRY_TAG)
#undef ENTRY_TAG
@ -142,6 +168,7 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final BASE_EMBEDDED {
};
index_t AllocateIndex(Entry constant_entry);
index_t AllocateIndexArray(Entry constant_entry, size_t size);
index_t AllocateReservedEntry(Smi* value);
struct ConstantArraySlice final : public ZoneObject {
@ -149,7 +176,7 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final BASE_EMBEDDED {
OperandSize operand_size);
void Reserve();
void Unreserve();
size_t Allocate(Entry entry);
size_t Allocate(Entry entry, size_t count = 1);
Entry& At(size_t index);
const Entry& At(size_t index) const;

View File

@ -47,21 +47,40 @@ void BlockBuilder::EndBlock() {
LoopBuilder::~LoopBuilder() {
DCHECK(continue_labels_.empty() || continue_labels_.is_bound());
DCHECK(header_labels_.empty() || header_labels_.is_bound());
BindBreakTarget();
// Restore the parent jump table.
if (generator_jump_table_location_ != nullptr) {
*generator_jump_table_location_ = parent_generator_jump_table_;
}
}
void LoopBuilder::LoopHeader(ZoneVector<BytecodeLabel>* additional_labels) {
void LoopBuilder::LoopHeader() {
// Jumps from before the loop header into the loop violate ordering
// requirements of bytecode basic blocks. The only entry into a loop
// must be the loop header. Surely breaks is okay? Not if nested
// and misplaced between the headers.
DCHECK(break_labels_.empty() && continue_labels_.empty());
builder()->Bind(&loop_header_);
if (additional_labels != nullptr) {
for (auto& label : *additional_labels) {
builder()->Bind(&label);
}
}
void LoopBuilder::LoopHeaderInGenerator(
BytecodeJumpTable** generator_jump_table, int first_resume_id,
int resume_count) {
// Bind all the resume points that are inside the loop to be at the loop
// header.
for (int id = first_resume_id; id < first_resume_id + resume_count; ++id) {
builder()->Bind(*generator_jump_table, id);
}
// Create the loop header.
LoopHeader();
// Create a new jump table for after the loop header for only these
// resume points.
generator_jump_table_location_ = generator_jump_table;
parent_generator_jump_table_ = *generator_jump_table;
*generator_jump_table =
builder()->AllocateJumpTable(resume_count, first_resume_id);
}
void LoopBuilder::JumpToHeader(int loop_depth) {
@ -74,11 +93,6 @@ void LoopBuilder::JumpToHeader(int loop_depth) {
builder()->JumpLoop(&loop_header_, level);
}
void LoopBuilder::EndLoop() {
BindBreakTarget();
header_labels_.BindToLabel(builder(), loop_header_);
}
void LoopBuilder::BindContinueTarget() { continue_labels_.Bind(builder()); }
SwitchBuilder::~SwitchBuilder() {

View File

@ -90,13 +90,15 @@ class V8_EXPORT_PRIVATE LoopBuilder final : public BreakableControlFlowBuilder {
explicit LoopBuilder(BytecodeArrayBuilder* builder)
: BreakableControlFlowBuilder(builder),
continue_labels_(builder->zone()),
header_labels_(builder->zone()) {}
generator_jump_table_location_(nullptr),
parent_generator_jump_table_(nullptr) {}
~LoopBuilder();
void LoopHeader(ZoneVector<BytecodeLabel>* additional_labels = nullptr);
void LoopHeader();
void LoopHeaderInGenerator(BytecodeJumpTable** parent_generator_jump_table,
int first_resume_id, int resume_count);
void JumpToHeader(int loop_depth);
void BindContinueTarget();
void EndLoop();
// This method is called when visiting continue statements in the AST.
// Inserts a jump to an unbound label that is patched when BindContinueTarget
@ -111,7 +113,13 @@ class V8_EXPORT_PRIVATE LoopBuilder final : public BreakableControlFlowBuilder {
// Unbound labels that identify jumps for continue statements in the code and
// jumps from checking the loop condition to the header for do-while loops.
BytecodeLabels continue_labels_;
BytecodeLabels header_labels_;
// While we're in the loop, we want to have a different jump table for
// generator switch statements. We restore it at the end of the loop.
// TODO(leszeks): Storing a pointer to the BytecodeGenerator's jump table
// field is ugly, figure out a better way to do this.
BytecodeJumpTable** generator_jump_table_location_;
BytecodeJumpTable* parent_generator_jump_table_;
};

View File

@ -2417,7 +2417,7 @@ IGNITION_HANDLER(TestTypeOf, InterpreterAssembler) {
// Jump <imm>
//
// Jump by number of bytes represented by the immediate operand |imm|.
// Jump by the number of bytes represented by the immediate operand |imm|.
IGNITION_HANDLER(Jump, InterpreterAssembler) {
Node* relative_jump = BytecodeOperandUImmWord(0);
Jump(relative_jump);
@ -2425,7 +2425,8 @@ IGNITION_HANDLER(Jump, InterpreterAssembler) {
// JumpConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool.
IGNITION_HANDLER(JumpConstant, InterpreterAssembler) {
Node* index = BytecodeOperandIdx(0);
Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
@ -2434,7 +2435,7 @@ IGNITION_HANDLER(JumpConstant, InterpreterAssembler) {
// JumpIfTrue <imm>
//
// Jump by number of bytes represented by an immediate operand if the
// Jump by the number of bytes represented by an immediate operand if the
// accumulator contains true. This only works for boolean inputs, and
// will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfTrue, InterpreterAssembler) {
@ -2448,9 +2449,9 @@ IGNITION_HANDLER(JumpIfTrue, InterpreterAssembler) {
// JumpIfTrueConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
// if the accumulator contains true. This only works for boolean inputs, and
// will misbehave if passed arbitrary input values.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the accumulator contains true. This only works for boolean inputs,
// and will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfTrueConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* index = BytecodeOperandIdx(0);
@ -2463,7 +2464,7 @@ IGNITION_HANDLER(JumpIfTrueConstant, InterpreterAssembler) {
// JumpIfFalse <imm>
//
// Jump by number of bytes represented by an immediate operand if the
// Jump by the number of bytes represented by an immediate operand if the
// accumulator contains false. This only works for boolean inputs, and
// will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfFalse, InterpreterAssembler) {
@ -2477,9 +2478,9 @@ IGNITION_HANDLER(JumpIfFalse, InterpreterAssembler) {
// JumpIfFalseConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
// if the accumulator contains false. This only works for boolean inputs, and
// will misbehave if passed arbitrary input values.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the accumulator contains false. This only works for boolean inputs,
// and will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfFalseConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* index = BytecodeOperandIdx(0);
@ -2492,7 +2493,7 @@ IGNITION_HANDLER(JumpIfFalseConstant, InterpreterAssembler) {
// JumpIfToBooleanTrue <imm>
//
// Jump by number of bytes represented by an immediate operand if the object
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is true when the object is cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanTrue, InterpreterAssembler) {
Node* value = GetAccumulator();
@ -2507,9 +2508,9 @@ IGNITION_HANDLER(JumpIfToBooleanTrue, InterpreterAssembler) {
// JumpIfToBooleanTrueConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
// if the object referenced by the accumulator is true when the object is cast
// to boolean.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is true when the object is
// cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanTrueConstant, InterpreterAssembler) {
Node* value = GetAccumulator();
Node* index = BytecodeOperandIdx(0);
@ -2524,7 +2525,7 @@ IGNITION_HANDLER(JumpIfToBooleanTrueConstant, InterpreterAssembler) {
// JumpIfToBooleanFalse <imm>
//
// Jump by number of bytes represented by an immediate operand if the object
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is false when the object is cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanFalse, InterpreterAssembler) {
Node* value = GetAccumulator();
@ -2539,9 +2540,9 @@ IGNITION_HANDLER(JumpIfToBooleanFalse, InterpreterAssembler) {
// JumpIfToBooleanFalseConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
// if the object referenced by the accumulator is false when the object is cast
// to boolean.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is false when the object is
// cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanFalseConstant, InterpreterAssembler) {
Node* value = GetAccumulator();
Node* index = BytecodeOperandIdx(0);
@ -2556,7 +2557,7 @@ IGNITION_HANDLER(JumpIfToBooleanFalseConstant, InterpreterAssembler) {
// JumpIfNull <imm>
//
// Jump by number of bytes represented by an immediate operand if the object
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the null constant.
IGNITION_HANDLER(JumpIfNull, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@ -2567,8 +2568,8 @@ IGNITION_HANDLER(JumpIfNull, InterpreterAssembler) {
// JumpIfNullConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
// if the object referenced by the accumulator is the null constant.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is the null constant.
IGNITION_HANDLER(JumpIfNullConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* null_value = HeapConstant(isolate()->factory()->null_value());
@ -2579,7 +2580,7 @@ IGNITION_HANDLER(JumpIfNullConstant, InterpreterAssembler) {
// JumpIfNotNull <imm>
//
// Jump by number of bytes represented by an immediate operand if the object
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is not the null constant.
IGNITION_HANDLER(JumpIfNotNull, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@ -2590,8 +2591,8 @@ IGNITION_HANDLER(JumpIfNotNull, InterpreterAssembler) {
// JumpIfNotNullConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
// if the object referenced by the accumulator is not the null constant.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is not the null constant.
IGNITION_HANDLER(JumpIfNotNullConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* null_value = HeapConstant(isolate()->factory()->null_value());
@ -2602,7 +2603,7 @@ IGNITION_HANDLER(JumpIfNotNullConstant, InterpreterAssembler) {
// JumpIfUndefined <imm>
//
// Jump by number of bytes represented by an immediate operand if the object
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the undefined constant.
IGNITION_HANDLER(JumpIfUndefined, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@ -2613,8 +2614,8 @@ IGNITION_HANDLER(JumpIfUndefined, InterpreterAssembler) {
// JumpIfUndefinedConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
// if the object referenced by the accumulator is the undefined constant.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is the undefined constant.
IGNITION_HANDLER(JumpIfUndefinedConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* undefined_value = HeapConstant(isolate()->factory()->undefined_value());
@ -2625,7 +2626,7 @@ IGNITION_HANDLER(JumpIfUndefinedConstant, InterpreterAssembler) {
// JumpIfNotUndefined <imm>
//
// Jump by number of bytes represented by an immediate operand if the object
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is not the undefined constant.
IGNITION_HANDLER(JumpIfNotUndefined, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@ -2636,8 +2637,9 @@ IGNITION_HANDLER(JumpIfNotUndefined, InterpreterAssembler) {
// JumpIfNotUndefinedConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
// if the object referenced by the accumulator is not the undefined constant.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is not the undefined
// constant.
IGNITION_HANDLER(JumpIfNotUndefinedConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* undefined_value = HeapConstant(isolate()->factory()->undefined_value());
@ -2648,7 +2650,7 @@ IGNITION_HANDLER(JumpIfNotUndefinedConstant, InterpreterAssembler) {
// JumpIfJSReceiver <imm>
//
// Jump by number of bytes represented by an immediate operand if the object
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is a JSReceiver.
IGNITION_HANDLER(JumpIfJSReceiver, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@ -2668,8 +2670,8 @@ IGNITION_HANDLER(JumpIfJSReceiver, InterpreterAssembler) {
// JumpIfJSReceiverConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool if
// the object referenced by the accumulator is a JSReceiver.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is a JSReceiver.
IGNITION_HANDLER(JumpIfJSReceiverConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* index = BytecodeOperandIdx(0);
@ -2690,7 +2692,7 @@ IGNITION_HANDLER(JumpIfJSReceiverConstant, InterpreterAssembler) {
// JumpIfNotHole <imm>
//
// Jump by number of bytes represented by an immediate operand if the object
// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the hole.
IGNITION_HANDLER(JumpIfNotHole, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@ -2701,8 +2703,8 @@ IGNITION_HANDLER(JumpIfNotHole, InterpreterAssembler) {
// JumpIfNotHoleConstant <idx>
//
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
// if the object referenced by the accumulator is the hole constant.
// Jump by the number of bytes in the Smi in the |idx| entry in the constant
// pool if the object referenced by the accumulator is the hole constant.
IGNITION_HANDLER(JumpIfNotHoleConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* the_hole_value = HeapConstant(isolate()->factory()->the_hole_value());
@ -2713,7 +2715,7 @@ IGNITION_HANDLER(JumpIfNotHoleConstant, InterpreterAssembler) {
// JumpLoop <imm> <loop_depth>
//
// Jump by number of bytes represented by the immediate operand |imm|. Also
// Jump by the 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|.
IGNITION_HANDLER(JumpLoop, InterpreterAssembler) {
@ -2740,6 +2742,37 @@ IGNITION_HANDLER(JumpLoop, InterpreterAssembler) {
}
}
// SwitchOnSmiNoFeedback <table_start> <table_length> <case_value_base>
//
// Jump by the number of bytes defined by a Smi in a table in the constant pool,
// where the table starts at |table_start| and has |table_length| entries.
// The table is indexed by the accumulator, minus |case_value_base|. If the
// case_value falls outside of the table |table_length|, fall-through to the
// next bytecode.
IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) {
Node* acc = GetAccumulator();
Node* table_start = BytecodeOperandIdx(0);
Node* table_length = BytecodeOperandUImmWord(1);
Node* case_value_base = BytecodeOperandImmIntPtr(2);
Label fall_through(this);
// The accumulator must be a Smi.
// TODO(leszeks): Add a bytecode with type feedback that allows other
// accumulator values.
CSA_ASSERT(this, TaggedIsSmi(acc));
Node* case_value = IntPtrSub(SmiUntag(acc), case_value_base);
GotoIf(IntPtrLessThan(case_value, IntPtrConstant(0)), &fall_through);
GotoIf(IntPtrGreaterThanOrEqual(case_value, table_length), &fall_through);
Node* entry = IntPtrAdd(table_start, case_value);
Node* relative_jump = LoadAndUntagConstantPoolEntry(entry);
Jump(relative_jump);
Bind(&fall_through);
Dispatch();
}
// CreateRegExpLiteral <pattern_idx> <literal_idx> <flags>
//
// Creates a regular expression literal for literal index <literal_idx> with

View File

@ -14786,6 +14786,19 @@ void BytecodeArray::Disassemble(std::ostream& os) {
os << " (" << jump_target << " @ " << iterator.GetJumpTargetOffset()
<< ")";
}
if (interpreter::Bytecodes::IsSwitch(iterator.current_bytecode())) {
os << " {";
bool first_entry = true;
for (const auto& entry : iterator.GetJumpTableTargetOffsets()) {
if (first_entry) {
first_entry = false;
} else {
os << ",";
}
os << " " << entry.case_value << ": @" << entry.target_offset;
}
os << " }";
}
os << std::endl;
iterator.Advance();
}

View File

@ -1052,6 +1052,7 @@
'interpreter/bytecode-register-optimizer.h',
'interpreter/bytecode-source-info.cc',
'interpreter/bytecode-source-info.h',
'interpreter/bytecode-jump-table.h',
'interpreter/bytecode-traits.h',
'interpreter/constant-array-builder.cc',
'interpreter/constant-array-builder.h',

View File

@ -16,23 +16,15 @@ snippet: "
"
frame size: 19
parameter count: 1
bytecode array length: 1015
bytecode array length: 1003
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(39),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(4),
B(ResumeGenerator), R(new_target),
B(Star), R(3),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(126),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrueConstant), U8(12),
B(LdaSmi), I8(2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrueConstant), U8(14),
B(SwitchOnSmiNoFeedback), U8(0), U8(3), I8(0),
B(LdaSmi), I8(79),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
@ -52,7 +44,7 @@ bytecodes: [
B(Mov), R(context), R(7),
B(Mov), R(context), R(8),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(CreateBlockContext), U8(3),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -60,33 +52,32 @@ bytecodes: [
B(StaContextSlot), R(1), U8(8), U8(0),
B(Mov), R(context), R(11),
B(Mov), R(context), R(12),
/* 43 S> */ B(CreateArrayLiteral), U8(1), U8(3), U8(17),
/* 43 S> */ B(CreateArrayLiteral), U8(4), U8(3), U8(17),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(2), U8(8),
B(LdaNamedProperty), R(13), U8(5), U8(8),
B(JumpIfUndefined), U8(17),
B(JumpIfNull), U8(15),
B(Star), R(14),
B(CallProperty0), R(14), R(13), U8(10),
B(JumpIfJSReceiver), U8(23),
B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0),
B(LdaNamedProperty), R(13), U8(3), U8(4),
B(LdaNamedProperty), R(13), U8(6), U8(4),
B(Star), R(14),
B(CallProperty0), R(14), R(13), U8(6),
B(Star), R(14),
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(14), U8(1),
/* 43 E> */ B(StaContextSlot), R(1), U8(6), U8(0),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(7), U8(1), I8(0),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(16),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(75),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(79),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kAbort), R(13), U8(1),
/* 40 S> */ B(LdaContextSlot), R(1), U8(6), U8(0),
B(Star), R(14),
B(LdaNamedProperty), R(14), U8(4), U8(14),
B(LdaNamedProperty), R(14), U8(8), U8(14),
B(Star), R(13),
/* 40 E> */ B(CallProperty0), R(13), R(14), U8(12),
B(StaContextSlot), R(1), U8(9), U8(0),
@ -139,11 +130,11 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(13), U8(1),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(5), U8(16),
B(LdaNamedProperty), R(13), U8(9), U8(16),
B(JumpIfToBooleanTrue), U8(56),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(6), U8(18),
B(LdaNamedProperty), R(13), U8(10), U8(18),
B(StaContextSlot), R(1), U8(11), U8(0),
B(LdaSmi), I8(2),
B(StaContextSlot), R(1), U8(8), U8(0),
@ -151,7 +142,7 @@ bytecodes: [
B(StaContextSlot), R(1), U8(5), U8(0),
/* 23 E> */ B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(7),
B(CreateBlockContext), U8(11),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -160,11 +151,11 @@ bytecodes: [
B(PopContext), R(2),
B(LdaZero),
B(StaContextSlot), R(1), U8(8), U8(0),
B(JumpLoop), U8(220), I8(0),
B(JumpLoop), U8(221), I8(0),
B(Jump), U8(48),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(8), U8(9),
B(CreateCatchContext), R(13), U8(12), U8(13),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
@ -194,15 +185,15 @@ bytecodes: [
B(Star), R(12),
B(LdaZero),
B(TestEqualStrict), R(12), U8(21),
B(JumpIfTrueConstant), U8(16),
B(JumpIfTrueConstant), U8(18),
B(LdaContextSlot), R(1), U8(6), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(10), U8(22),
B(LdaNamedProperty), R(12), U8(14), U8(22),
B(StaContextSlot), R(1), U8(12), U8(0),
B(LdaContextSlot), R(1), U8(12), U8(0),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(JumpConstant), U8(15),
B(JumpConstant), U8(17),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(LdaSmi), I8(1),
@ -214,7 +205,7 @@ bytecodes: [
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(130),
B(Star), R(12),
B(LdaConstant), U8(11),
B(LdaConstant), U8(15),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kNewTypeError), R(12), U8(2),
B(Throw),
@ -265,14 +256,14 @@ bytecodes: [
B(Star), R(6),
B(LdaZero),
B(Star), R(5),
B(JumpConstant), U8(18),
B(JumpConstant), U8(20),
B(Ldar), R(15),
B(ReThrow),
B(Ldar), R(15),
B(Jump), U8(20),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(8), U8(13),
B(CreateCatchContext), R(13), U8(12), U8(16),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
@ -376,7 +367,7 @@ bytecodes: [
B(Jump), U8(54),
B(Star), R(9),
B(Ldar), R(closure),
B(CreateCatchContext), R(9), U8(8), U8(17),
B(CreateCatchContext), R(9), U8(12), U8(19),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
@ -449,10 +440,14 @@ bytecodes: [
/* 57 S> */ B(Return),
]
constant pool: [
Smi [116],
Smi [546],
Smi [692],
FIXED_ARRAY_TYPE,
TUPLE2_TYPE,
SYMBOL_TYPE,
SYMBOL_TYPE,
Smi [83],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
@ -461,20 +456,18 @@ constant pool: [
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [549],
FIXED_ARRAY_TYPE,
Smi [689],
Smi [344],
Smi [367],
FIXED_ARRAY_TYPE,
Smi [315],
]
handlers: [
[74, 928, 934],
[77, 874, 876],
[94, 415, 421],
[97, 367, 369],
[508, 632, 634],
[61, 916, 922],
[64, 862, 864],
[81, 403, 409],
[84, 355, 357],
[496, 620, 622],
]
---
@ -486,23 +479,15 @@ snippet: "
"
frame size: 19
parameter count: 1
bytecode array length: 1073
bytecode array length: 1061
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(39),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(4),
B(ResumeGenerator), R(new_target),
B(Star), R(3),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(126),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrueConstant), U8(12),
B(LdaSmi), I8(2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrueConstant), U8(14),
B(SwitchOnSmiNoFeedback), U8(0), U8(3), I8(0),
B(LdaSmi), I8(79),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
@ -522,7 +507,7 @@ bytecodes: [
B(Mov), R(context), R(7),
B(Mov), R(context), R(8),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(CreateBlockContext), U8(3),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -530,33 +515,32 @@ bytecodes: [
B(StaContextSlot), R(1), U8(8), U8(0),
B(Mov), R(context), R(11),
B(Mov), R(context), R(12),
/* 43 S> */ B(CreateArrayLiteral), U8(1), U8(3), U8(17),
/* 43 S> */ B(CreateArrayLiteral), U8(4), U8(3), U8(17),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(2), U8(8),
B(LdaNamedProperty), R(13), U8(5), U8(8),
B(JumpIfUndefined), U8(17),
B(JumpIfNull), U8(15),
B(Star), R(14),
B(CallProperty0), R(14), R(13), U8(10),
B(JumpIfJSReceiver), U8(23),
B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0),
B(LdaNamedProperty), R(13), U8(3), U8(4),
B(LdaNamedProperty), R(13), U8(6), U8(4),
B(Star), R(14),
B(CallProperty0), R(14), R(13), U8(6),
B(Star), R(14),
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(14), U8(1),
/* 43 E> */ B(StaContextSlot), R(1), U8(6), U8(0),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(7), U8(1), I8(0),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(16),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(75),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(79),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kAbort), R(13), U8(1),
/* 40 S> */ B(LdaContextSlot), R(1), U8(6), U8(0),
B(Star), R(14),
B(LdaNamedProperty), R(14), U8(4), U8(14),
B(LdaNamedProperty), R(14), U8(8), U8(14),
B(Star), R(13),
/* 40 E> */ B(CallProperty0), R(13), R(14), U8(12),
B(StaContextSlot), R(1), U8(9), U8(0),
@ -609,11 +593,11 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(13), U8(1),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(5), U8(16),
B(LdaNamedProperty), R(13), U8(9), U8(16),
B(JumpIfToBooleanTrue), U8(68),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(6), U8(18),
B(LdaNamedProperty), R(13), U8(10), U8(18),
B(StaContextSlot), R(1), U8(11), U8(0),
B(LdaSmi), I8(2),
B(StaContextSlot), R(1), U8(8), U8(0),
@ -621,7 +605,7 @@ bytecodes: [
B(StaContextSlot), R(1), U8(5), U8(0),
/* 23 E> */ B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(7),
B(CreateBlockContext), U8(11),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -641,7 +625,7 @@ bytecodes: [
B(Jump), U8(48),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(8), U8(9),
B(CreateCatchContext), R(13), U8(12), U8(13),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
@ -671,15 +655,15 @@ bytecodes: [
B(Star), R(12),
B(LdaZero),
B(TestEqualStrict), R(12), U8(21),
B(JumpIfTrueConstant), U8(16),
B(JumpIfTrueConstant), U8(18),
B(LdaContextSlot), R(1), U8(6), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(10), U8(22),
B(LdaNamedProperty), R(12), U8(14), U8(22),
B(StaContextSlot), R(1), U8(12), U8(0),
B(LdaContextSlot), R(1), U8(12), U8(0),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(JumpConstant), U8(15),
B(JumpConstant), U8(17),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(LdaSmi), I8(1),
@ -691,7 +675,7 @@ bytecodes: [
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(130),
B(Star), R(12),
B(LdaConstant), U8(11),
B(LdaConstant), U8(15),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kNewTypeError), R(12), U8(2),
B(Throw),
@ -742,14 +726,14 @@ bytecodes: [
B(Star), R(6),
B(LdaZero),
B(Star), R(5),
B(JumpConstant), U8(18),
B(JumpConstant), U8(20),
B(Ldar), R(15),
B(ReThrow),
B(Ldar), R(15),
B(Jump), U8(20),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(8), U8(13),
B(CreateCatchContext), R(13), U8(12), U8(16),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
@ -864,7 +848,7 @@ bytecodes: [
B(Jump), U8(54),
B(Star), R(9),
B(Ldar), R(closure),
B(CreateCatchContext), R(9), U8(8), U8(17),
B(CreateCatchContext), R(9), U8(12), U8(19),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
@ -948,10 +932,14 @@ bytecodes: [
/* 68 S> */ B(Return),
]
constant pool: [
Smi [116],
Smi [558],
Smi [704],
FIXED_ARRAY_TYPE,
TUPLE2_TYPE,
SYMBOL_TYPE,
SYMBOL_TYPE,
Smi [83],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
@ -960,20 +948,18 @@ constant pool: [
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [561],
FIXED_ARRAY_TYPE,
Smi [701],
Smi [344],
Smi [367],
FIXED_ARRAY_TYPE,
Smi [338],
]
handlers: [
[74, 963, 969],
[77, 909, 911],
[94, 427, 433],
[97, 379, 381],
[520, 644, 646],
[61, 951, 957],
[64, 897, 899],
[81, 415, 421],
[84, 367, 369],
[508, 632, 634],
]
---
@ -988,23 +974,15 @@ snippet: "
"
frame size: 19
parameter count: 1
bytecode array length: 1049
bytecode array length: 1037
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(39),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(4),
B(ResumeGenerator), R(new_target),
B(Star), R(3),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(126),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrueConstant), U8(12),
B(LdaSmi), I8(2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrueConstant), U8(14),
B(SwitchOnSmiNoFeedback), U8(0), U8(3), I8(0),
B(LdaSmi), I8(79),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
@ -1024,7 +1002,7 @@ bytecodes: [
B(Mov), R(context), R(7),
B(Mov), R(context), R(8),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(CreateBlockContext), U8(3),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -1032,33 +1010,32 @@ bytecodes: [
B(StaContextSlot), R(1), U8(8), U8(0),
B(Mov), R(context), R(11),
B(Mov), R(context), R(12),
/* 43 S> */ B(CreateArrayLiteral), U8(1), U8(3), U8(17),
/* 43 S> */ B(CreateArrayLiteral), U8(4), U8(3), U8(17),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(2), U8(8),
B(LdaNamedProperty), R(13), U8(5), U8(8),
B(JumpIfUndefined), U8(17),
B(JumpIfNull), U8(15),
B(Star), R(14),
B(CallProperty0), R(14), R(13), U8(10),
B(JumpIfJSReceiver), U8(23),
B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0),
B(LdaNamedProperty), R(13), U8(3), U8(4),
B(LdaNamedProperty), R(13), U8(6), U8(4),
B(Star), R(14),
B(CallProperty0), R(14), R(13), U8(6),
B(Star), R(14),
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(14), U8(1),
/* 43 E> */ B(StaContextSlot), R(1), U8(6), U8(0),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(7), U8(1), I8(0),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(16),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(75),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(79),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kAbort), R(13), U8(1),
/* 40 S> */ B(LdaContextSlot), R(1), U8(6), U8(0),
B(Star), R(14),
B(LdaNamedProperty), R(14), U8(4), U8(14),
B(LdaNamedProperty), R(14), U8(8), U8(14),
B(Star), R(13),
/* 40 E> */ B(CallProperty0), R(13), R(14), U8(12),
B(StaContextSlot), R(1), U8(9), U8(0),
@ -1111,11 +1088,11 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(13), U8(1),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(5), U8(16),
B(LdaNamedProperty), R(13), U8(9), U8(16),
B(JumpIfToBooleanTrue), U8(90),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(6), U8(18),
B(LdaNamedProperty), R(13), U8(10), U8(18),
B(StaContextSlot), R(1), U8(11), U8(0),
B(LdaSmi), I8(2),
B(StaContextSlot), R(1), U8(8), U8(0),
@ -1123,7 +1100,7 @@ bytecodes: [
B(StaContextSlot), R(1), U8(5), U8(0),
/* 23 E> */ B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(7),
B(CreateBlockContext), U8(11),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -1148,11 +1125,11 @@ bytecodes: [
B(PopContext), R(2),
B(LdaZero),
B(StaContextSlot), R(1), U8(8), U8(0),
B(JumpLoop), U8(254), I8(0),
B(JumpLoop), U8(255), I8(0),
B(Jump), U8(48),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(8), U8(9),
B(CreateCatchContext), R(13), U8(12), U8(13),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
@ -1182,15 +1159,15 @@ bytecodes: [
B(Star), R(12),
B(LdaZero),
B(TestEqualStrict), R(12), U8(23),
B(JumpIfTrueConstant), U8(16),
B(JumpIfTrueConstant), U8(18),
B(LdaContextSlot), R(1), U8(6), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(10), U8(24),
B(LdaNamedProperty), R(12), U8(14), U8(24),
B(StaContextSlot), R(1), U8(12), U8(0),
B(LdaContextSlot), R(1), U8(12), U8(0),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(JumpConstant), U8(15),
B(JumpConstant), U8(17),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(LdaSmi), I8(1),
@ -1202,7 +1179,7 @@ bytecodes: [
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(130),
B(Star), R(12),
B(LdaConstant), U8(11),
B(LdaConstant), U8(15),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kNewTypeError), R(12), U8(2),
B(Throw),
@ -1253,14 +1230,14 @@ bytecodes: [
B(Star), R(6),
B(LdaZero),
B(Star), R(5),
B(JumpConstant), U8(18),
B(JumpConstant), U8(20),
B(Ldar), R(15),
B(ReThrow),
B(Ldar), R(15),
B(Jump), U8(20),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(8), U8(13),
B(CreateCatchContext), R(13), U8(12), U8(16),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
@ -1364,7 +1341,7 @@ bytecodes: [
B(Jump), U8(54),
B(Star), R(9),
B(Ldar), R(closure),
B(CreateCatchContext), R(9), U8(8), U8(17),
B(CreateCatchContext), R(9), U8(12), U8(19),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
@ -1437,10 +1414,14 @@ bytecodes: [
/* 114 S> */ B(Return),
]
constant pool: [
Smi [116],
Smi [580],
Smi [726],
FIXED_ARRAY_TYPE,
TUPLE2_TYPE,
SYMBOL_TYPE,
SYMBOL_TYPE,
Smi [83],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
@ -1449,20 +1430,18 @@ constant pool: [
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [583],
FIXED_ARRAY_TYPE,
Smi [723],
Smi [344],
Smi [367],
FIXED_ARRAY_TYPE,
Smi [315],
]
handlers: [
[74, 962, 968],
[77, 908, 910],
[94, 449, 455],
[97, 401, 403],
[542, 666, 668],
[61, 950, 956],
[64, 896, 898],
[81, 437, 443],
[84, 389, 391],
[530, 654, 656],
]
---
@ -1473,266 +1452,251 @@ snippet: "
}
f();
"
frame size: 14
frame size: 12
parameter count: 1
bytecode array length: 573
bytecode array length: 533
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(22),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(3),
B(ResumeGenerator), R(new_target),
B(Star), R(2),
B(LdaSmi), I8(79),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(2),
B(CreateFunctionContext), U8(9),
B(PushContext), R(0),
B(Mov), R(closure), R(4),
B(Mov), R(this), R(5),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(4), U8(2),
B(StaCurrentContextSlot), U8(4),
/* 16 E> */ B(StackCheck),
B(LdaUndefined),
B(Star), R(4),
B(CallJSRuntime), U8(%async_function_promise_create), R(4), U8(1),
B(Star), R(2),
B(CallJSRuntime), U8(%async_function_promise_create), R(2), U8(1),
B(StaCurrentContextSlot), U8(12),
B(Mov), R(context), R(6),
B(Mov), R(context), R(7),
/* 31 S> */ B(CreateObjectLiteral), U8(0), U8(3), U8(1), R(8),
B(Ldar), R(8),
B(Mov), R(context), R(4),
B(Mov), R(context), R(5),
/* 31 S> */ B(CreateObjectLiteral), U8(0), U8(3), U8(1), R(6),
B(Ldar), R(6),
/* 31 E> */ B(StaCurrentContextSlot), U8(5),
B(LdaZero),
B(StaCurrentContextSlot), U8(8),
B(Mov), R(context), R(10),
B(Mov), R(context), R(11),
B(Mov), R(context), R(8),
B(Mov), R(context), R(9),
/* 68 S> */ B(CreateArrayLiteral), U8(1), U8(4), U8(17),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(2), U8(5),
B(Star), R(13),
B(CallProperty0), R(13), R(12), U8(7),
B(Star), R(10),
B(LdaNamedProperty), R(10), U8(2), U8(5),
B(Star), R(11),
B(CallProperty0), R(11), R(10), U8(7),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
/* 68 E> */ B(StaCurrentContextSlot), U8(6),
/* 65 S> */ B(LdaCurrentContextSlot), U8(6),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(3), U8(11),
B(Star), R(12),
/* 65 E> */ B(CallProperty0), R(12), R(13), U8(9),
B(Star), R(11),
B(LdaNamedProperty), R(11), U8(3), U8(11),
B(Star), R(10),
/* 65 E> */ B(CallProperty0), R(10), R(11), U8(9),
/* 65 E> */ B(StaCurrentContextSlot), U8(7),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(12), U8(1),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(10), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(11),
B(LdaCurrentContextSlot), U8(7),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(Star), R(10),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(LdaCurrentContextSlot), U8(7),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(4), U8(13),
B(Star), R(10),
B(LdaNamedProperty), R(10), U8(4), U8(13),
B(JumpIfToBooleanTrue), U8(42),
B(LdaImmutableCurrentContextSlot), U8(5),
B(Star), R(12),
B(Star), R(10),
B(LdaCurrentContextSlot), U8(7),
B(Star), R(13),
/* 58 E> */ B(LdaNamedProperty), R(13), U8(5), U8(15),
B(Star), R(11),
/* 58 E> */ B(LdaNamedProperty), R(11), U8(5), U8(15),
B(StaCurrentContextSlot), U8(9),
B(LdaSmi), I8(2),
B(StaCurrentContextSlot), U8(8),
B(LdaCurrentContextSlot), U8(9),
B(StaNamedPropertySloppy), R(12), U8(6), U8(17),
B(StaNamedPropertySloppy), R(10), U8(6), U8(17),
/* 53 E> */ B(StackCheck),
/* 79 S> */ B(LdaImmutableCurrentContextSlot), U8(5),
B(Star), R(12),
/* 87 E> */ B(LdaNamedProperty), R(12), U8(6), U8(19),
B(Star), R(9),
B(Star), R(10),
/* 87 E> */ B(LdaNamedProperty), R(10), U8(6), U8(19),
B(Star), R(7),
B(LdaZero),
B(Star), R(8),
B(Star), R(6),
B(Jump), U8(62),
B(Jump), U8(48),
B(Star), R(12),
B(Star), R(10),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(7), U8(8),
B(Star), R(11),
B(CreateCatchContext), R(10), U8(7), U8(8),
B(Star), R(9),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(11),
B(Ldar), R(9),
B(PushContext), R(1),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(Star), R(10),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(12), U8(21),
B(TestEqualStrict), R(10), U8(21),
B(JumpIfFalse), U8(8),
B(LdaSmi), I8(1),
B(StaContextSlot), R(1), U8(8), U8(0),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kReThrow), R(12), U8(1),
B(Star), R(10),
B(CallRuntime), U16(Runtime::kReThrow), R(10), U8(1),
B(PopContext), R(1),
B(LdaSmi), I8(-1),
B(Star), R(8),
B(Star), R(6),
B(Jump), U8(8),
B(Star), R(9),
B(Star), R(7),
B(LdaSmi), I8(1),
B(Star), R(8),
B(Star), R(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(10),
B(Star), R(8),
B(LdaCurrentContextSlot), U8(8),
B(Star), R(11),
B(Star), R(9),
B(LdaZero),
B(TestEqualStrict), R(11), U8(22),
B(TestEqualStrict), R(9), U8(22),
B(JumpIfTrue), U8(126),
B(LdaCurrentContextSlot), U8(6),
B(Star), R(11),
B(LdaNamedProperty), R(11), U8(9), U8(23),
B(Star), R(9),
B(LdaNamedProperty), R(9), U8(9), U8(23),
B(StaCurrentContextSlot), U8(10),
B(LdaCurrentContextSlot), U8(10),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(109),
B(LdaCurrentContextSlot), U8(8),
B(Star), R(11),
B(Star), R(9),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(11), U8(26),
B(TestEqualStrict), R(9), U8(26),
B(JumpIfFalse), U8(63),
B(LdaCurrentContextSlot), U8(10),
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(130),
B(Star), R(11),
B(Star), R(9),
B(LdaConstant), U8(10),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(Star), R(10),
B(CallRuntime), U16(Runtime::kNewTypeError), R(9), U8(2),
B(Throw),
B(Mov), R(context), R(11),
B(Mov), R(context), R(9),
B(LdaCurrentContextSlot), U8(10),
B(Star), R(12),
B(Star), R(10),
B(LdaCurrentContextSlot), U8(6),
B(Star), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
B(Jump), U8(20),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(7), U8(11),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(10), U8(2),
B(Jump), U8(20),
B(Star), R(10),
B(Ldar), R(closure),
B(CreateCatchContext), R(10), U8(7), U8(11),
B(Star), R(9),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(11),
B(Ldar), R(9),
B(PushContext), R(1),
B(PopContext), R(1),
B(Jump), U8(37),
B(LdaCurrentContextSlot), U8(10),
B(Star), R(11),
B(Star), R(9),
B(LdaCurrentContextSlot), U8(6),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(9), U8(2),
B(StaCurrentContextSlot), U8(11),
B(LdaCurrentContextSlot), U8(11),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(11), U8(1),
B(Star), R(9),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(9), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(11),
B(LdaCurrentContextSlot), U8(11),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(Ldar), R(10),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(Ldar), R(8),
B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(8),
B(TestEqualStrictNoFeedback), R(6),
B(JumpIfTrue), U8(10),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(8),
B(TestEqualStrictNoFeedback), R(6),
B(JumpIfTrue), U8(12),
B(Jump), U8(13),
B(LdaZero),
B(Star), R(4),
B(Mov), R(9), R(5),
B(Star), R(2),
B(Mov), R(7), R(3),
B(Jump), U8(95),
B(Ldar), R(9),
B(Ldar), R(7),
B(ReThrow),
B(LdaUndefined),
B(Star), R(8),
B(Star), R(6),
B(LdaCurrentContextSlot), U8(12),
B(Star), R(9),
B(Star), R(7),
B(LdaUndefined),
B(Star), R(10),
B(CallJSRuntime), U8(%promise_resolve), R(8), U8(3),
B(Star), R(8),
B(CallJSRuntime), U8(%promise_resolve), R(6), U8(3),
B(LdaCurrentContextSlot), U8(12),
B(Star), R(5),
B(Star), R(3),
B(LdaSmi), I8(1),
B(Star), R(4),
B(Star), R(2),
B(Jump), U8(68),
B(Jump), U8(54),
B(Star), R(8),
B(Star), R(6),
B(Ldar), R(closure),
B(CreateCatchContext), R(8), U8(7), U8(12),
B(Star), R(7),
B(CreateCatchContext), R(6), U8(7), U8(12),
B(Star), R(5),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(7),
B(Ldar), R(5),
B(PushContext), R(1),
B(LdaUndefined),
B(Star), R(8),
B(Star), R(6),
B(LdaContextSlot), R(1), U8(12), U8(0),
B(Star), R(9),
B(Star), R(7),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(10),
B(Star), R(8),
B(LdaFalse),
B(Star), R(11),
B(CallJSRuntime), U8(%promise_internal_reject), R(8), U8(4),
B(Star), R(9),
B(CallJSRuntime), U8(%promise_internal_reject), R(6), U8(4),
B(LdaContextSlot), R(1), U8(12), U8(0),
B(PopContext), R(1),
B(PopContext), R(1),
B(Star), R(5),
B(Star), R(3),
B(LdaSmi), I8(2),
B(Star), R(4),
B(Star), R(2),
B(Jump), U8(14),
B(LdaSmi), I8(-1),
B(Star), R(4),
B(Star), R(2),
B(Jump), U8(8),
B(Star), R(5),
B(Star), R(3),
B(LdaSmi), I8(3),
B(Star), R(4),
B(Star), R(2),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(6),
B(Star), R(4),
B(LdaUndefined),
B(Star), R(7),
B(Star), R(5),
B(LdaCurrentContextSlot), U8(12),
B(Star), R(8),
B(CallJSRuntime), U8(%async_function_promise_release), R(7), U8(2),
B(Ldar), R(6),
B(Star), R(6),
B(CallJSRuntime), U8(%async_function_promise_release), R(5), U8(2),
B(Ldar), R(4),
B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(4),
B(TestEqualStrictNoFeedback), R(2),
B(JumpIfTrue), U8(22),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(4),
B(TestEqualStrictNoFeedback), R(2),
B(JumpIfTrue), U8(33),
B(LdaSmi), I8(2),
B(TestEqualStrictNoFeedback), R(4),
B(TestEqualStrictNoFeedback), R(2),
B(JumpIfTrue), U8(30),
B(LdaSmi), I8(3),
B(TestEqualStrictNoFeedback), R(4),
B(TestEqualStrictNoFeedback), R(2),
B(JumpIfTrue), U8(27),
B(Jump), U8(28),
B(LdaCurrentContextSlot), U8(12),
B(Star), R(8),
B(Star), R(6),
B(LdaUndefined),
B(Star), R(7),
B(Mov), R(5), R(9),
B(CallJSRuntime), U8(%promise_resolve), R(7), U8(3),
B(Ldar), R(8),
B(Star), R(5),
B(Mov), R(3), R(7),
B(CallJSRuntime), U8(%promise_resolve), R(5), U8(3),
B(Ldar), R(6),
/* 96 S> */ B(Return),
B(Ldar), R(5),
B(Ldar), R(3),
/* 96 S> */ B(Return),
B(Ldar), R(5),
B(Ldar), R(3),
/* 96 S> */ B(Return),
B(Ldar), R(5),
B(Ldar), R(3),
B(ReThrow),
B(LdaUndefined),
/* 96 S> */ B(Return),
@ -1753,10 +1717,10 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[57, 490, 496],
[60, 436, 438],
[75, 235, 241],
[78, 187, 189],
[316, 328, 330],
[17, 450, 456],
[20, 396, 398],
[35, 195, 201],
[38, 147, 149],
[276, 288, 290],
]

View File

@ -648,17 +648,15 @@ snippet: "
"
frame size: 15
parameter count: 2
bytecode array length: 620
bytecode array length: 619
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(5),
B(ResumeGenerator), R(new_target),
B(Star), R(4),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(4),
B(JumpIfTrue), U8(54),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kAbort), R(6), U8(1),
@ -701,11 +699,11 @@ bytecodes: [
B(Star), R(7),
B(LdaZero),
B(Star), R(6),
B(JumpConstant), U8(12),
B(JumpConstant), U8(13),
B(Ldar), R(11),
/* 11 E> */ B(Throw),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(CreateBlockContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -715,7 +713,7 @@ bytecodes: [
B(Mov), R(context), R(12),
/* 35 S> */ B(LdaImmutableContextSlot), R(1), U8(4), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(1), U8(3),
B(LdaNamedProperty), R(13), U8(2), U8(3),
B(Star), R(14),
B(CallProperty0), R(14), R(13), U8(5),
B(JumpIfJSReceiver), U8(7),
@ -723,7 +721,7 @@ bytecodes: [
/* 35 E> */ B(StaContextSlot), R(1), U8(7), U8(0),
/* 32 S> */ B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(14),
B(LdaNamedProperty), R(14), U8(2), U8(9),
B(LdaNamedProperty), R(14), U8(3), U8(9),
B(Star), R(13),
/* 32 E> */ B(CallProperty0), R(13), R(14), U8(7),
/* 32 E> */ B(StaContextSlot), R(1), U8(8), U8(0),
@ -736,11 +734,11 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(13), U8(1),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(3), U8(11),
B(LdaNamedProperty), R(13), U8(4), U8(11),
B(JumpIfToBooleanTrue), U8(73),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(4), U8(13),
B(LdaNamedProperty), R(13), U8(5), U8(13),
B(StaContextSlot), R(1), U8(10), U8(0),
B(LdaSmi), I8(2),
B(StaContextSlot), R(1), U8(9), U8(0),
@ -748,14 +746,14 @@ bytecodes: [
B(StaContextSlot), R(1), U8(6), U8(0),
/* 21 E> */ B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(5),
B(CreateBlockContext), U8(6),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaContextSlot), R(1), U8(6), U8(0),
B(StaCurrentContextSlot), U8(4),
B(Ldar), R(closure),
B(CreateBlockContext), U8(6),
B(CreateBlockContext), U8(7),
B(PushContext), R(3),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -769,7 +767,7 @@ bytecodes: [
B(Jump), U8(44),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(7), U8(8),
B(CreateCatchContext), R(13), U8(8), U8(9),
B(PushContext), R(2),
B(Star), R(12),
B(LdaContextSlot), R(1), U8(9), U8(0),
@ -799,7 +797,7 @@ bytecodes: [
B(JumpIfTrue), U8(150),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(9), U8(17),
B(LdaNamedProperty), R(12), U8(10), U8(17),
B(StaContextSlot), R(1), U8(11), U8(0),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(TestUndetectable),
@ -816,7 +814,7 @@ bytecodes: [
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(130),
B(Star), R(12),
B(LdaConstant), U8(10),
B(LdaConstant), U8(11),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kNewTypeError), R(12), U8(2),
B(Throw),
@ -829,7 +827,7 @@ bytecodes: [
B(Jump), U8(20),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(7), U8(11),
B(CreateCatchContext), R(13), U8(8), U8(12),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
@ -912,6 +910,7 @@ bytecodes: [
/* 55 S> */ B(Return),
]
constant pool: [
Smi [56],
FIXED_ARRAY_TYPE,
SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
@ -927,10 +926,10 @@ constant pool: [
Smi [449],
]
handlers: [
[57, 553, 559],
[138, 335, 341],
[141, 291, 293],
[427, 443, 445],
[56, 552, 558],
[137, 334, 340],
[140, 290, 292],
[426, 442, 444],
]
---
@ -942,20 +941,15 @@ snippet: "
"
frame size: 18
parameter count: 2
bytecode array length: 747
bytecode array length: 740
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(33),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(4),
B(ResumeGenerator), R(new_target),
B(Star), R(3),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(60),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(150),
B(SwitchOnSmiNoFeedback), U8(0), U8(2), I8(0),
B(LdaSmi), I8(79),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
@ -998,11 +992,11 @@ bytecodes: [
B(Star), R(6),
B(LdaZero),
B(Star), R(5),
B(JumpConstant), U8(11),
B(JumpConstant), U8(14),
B(Ldar), R(10),
/* 11 E> */ B(Throw),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(CreateBlockContext), U8(2),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -1012,24 +1006,23 @@ bytecodes: [
B(Mov), R(context), R(11),
/* 35 S> */ B(LdaImmutableContextSlot), R(1), U8(4), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(1), U8(3),
B(LdaNamedProperty), R(12), U8(3), U8(3),
B(Star), R(13),
B(CallProperty0), R(13), R(12), U8(5),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
/* 35 E> */ B(StaContextSlot), R(1), U8(7), U8(0),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(4), U8(1), I8(1),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(17),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(134),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(79),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kAbort), R(12), U8(1),
/* 32 S> */ B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(2), U8(9),
B(LdaNamedProperty), R(13), U8(5), U8(9),
B(Star), R(12),
/* 32 E> */ B(CallProperty0), R(12), R(13), U8(7),
/* 32 E> */ B(StaContextSlot), R(1), U8(8), U8(0),
@ -1042,11 +1035,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(3), U8(11),
B(LdaNamedProperty), R(12), U8(6), U8(11),
B(JumpIfToBooleanTrue), U8(144),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(4), U8(13),
B(LdaNamedProperty), R(12), U8(7), U8(13),
B(StaContextSlot), R(1), U8(10), U8(0),
B(LdaSmi), I8(2),
B(StaContextSlot), R(1), U8(9), U8(0),
@ -1054,7 +1047,7 @@ bytecodes: [
B(StaContextSlot), R(1), U8(6), U8(0),
/* 21 E> */ B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(5),
B(CreateBlockContext), U8(8),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -1107,7 +1100,7 @@ bytecodes: [
B(Jump), U8(44),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(6), U8(7),
B(CreateCatchContext), R(12), U8(9), U8(10),
B(PushContext), R(2),
B(Star), R(11),
B(LdaContextSlot), R(1), U8(9), U8(0),
@ -1137,7 +1130,7 @@ bytecodes: [
B(JumpIfTrue), U8(150),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(11),
B(LdaNamedProperty), R(11), U8(8), U8(17),
B(LdaNamedProperty), R(11), U8(11), U8(17),
B(StaContextSlot), R(1), U8(11), U8(0),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(TestUndetectable),
@ -1154,7 +1147,7 @@ bytecodes: [
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(130),
B(Star), R(11),
B(LdaConstant), U8(9),
B(LdaConstant), U8(12),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(Throw),
@ -1167,7 +1160,7 @@ bytecodes: [
B(Jump), U8(20),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(6), U8(10),
B(CreateCatchContext), R(12), U8(9), U8(13),
B(Star), R(11),
B(LdaTheHole),
B(SetPendingMessage),
@ -1264,8 +1257,11 @@ bytecodes: [
/* 49 S> */ B(Return),
]
constant pool: [
Smi [56],
Smi [152],
FIXED_ARRAY_TYPE,
SYMBOL_TYPE,
Smi [142],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
@ -1278,10 +1274,10 @@ constant pool: [
Smi [561],
]
handlers: [
[63, 671, 677],
[144, 433, 439],
[147, 389, 391],
[526, 542, 544],
[56, 664, 670],
[137, 426, 432],
[140, 382, 384],
[519, 535, 537],
]
---
@ -1291,36 +1287,21 @@ snippet: "
}
f([1, 2, 3]);
"
frame size: 16
frame size: 14
parameter count: 2
bytecode array length: 613
bytecode array length: 573
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(22),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(5),
B(ResumeGenerator), R(new_target),
B(Star), R(4),
B(LdaSmi), I8(79),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kAbort), R(6), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(4),
B(CreateFunctionContext), U8(10),
B(PushContext), R(0),
B(Ldar), R(arg0),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(closure), R(6),
B(Mov), R(this), R(7),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(6), U8(2),
B(StaCurrentContextSlot), U8(5),
/* 16 E> */ B(StackCheck),
B(LdaUndefined),
B(Star), R(6),
B(CallJSRuntime), U8(%async_function_promise_create), R(6), U8(1),
B(Star), R(4),
B(CallJSRuntime), U8(%async_function_promise_create), R(4), U8(1),
B(StaCurrentContextSlot), U8(13),
B(Mov), R(context), R(8),
B(Mov), R(context), R(9),
B(Mov), R(context), R(6),
B(Mov), R(context), R(7),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(PushContext), R(1),
@ -1328,36 +1309,36 @@ bytecodes: [
B(StaCurrentContextSlot), U8(4),
B(LdaZero),
B(StaContextSlot), R(1), U8(9), U8(0),
B(Mov), R(context), R(12),
B(Mov), R(context), R(13),
B(Mov), R(context), R(10),
B(Mov), R(context), R(11),
/* 40 S> */ B(LdaImmutableContextSlot), R(1), U8(4), U8(0),
B(Star), R(14),
B(LdaNamedProperty), R(14), U8(1), U8(3),
B(Star), R(15),
B(CallProperty0), R(15), R(14), U8(5),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(1), U8(3),
B(Star), R(13),
B(CallProperty0), R(13), R(12), U8(5),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
/* 40 E> */ B(StaContextSlot), R(1), U8(7), U8(0),
/* 37 S> */ B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(15),
B(LdaNamedProperty), R(15), U8(2), U8(9),
B(Star), R(14),
/* 37 E> */ B(CallProperty0), R(14), R(15), U8(7),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(2), U8(9),
B(Star), R(12),
/* 37 E> */ B(CallProperty0), R(12), R(13), U8(7),
/* 37 E> */ B(StaContextSlot), R(1), U8(8), U8(0),
B(Star), R(14),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(14), U8(1),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(12), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(13),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(14),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(14), U8(1),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(14),
B(LdaNamedProperty), R(14), U8(3), U8(11),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(3), U8(11),
B(JumpIfToBooleanTrue), U8(73),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(14),
B(LdaNamedProperty), R(14), U8(4), U8(13),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(4), U8(13),
B(StaContextSlot), R(1), U8(10), U8(0),
B(LdaSmi), I8(2),
B(StaContextSlot), R(1), U8(9), U8(0),
@ -1384,172 +1365,172 @@ bytecodes: [
B(StaContextSlot), R(1), U8(9), U8(0),
B(JumpLoop), U8(120), I8(0),
B(Jump), U8(48),
B(Star), R(14),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(14), U8(7), U8(8),
B(Star), R(13),
B(CreateCatchContext), R(12), U8(7), U8(8),
B(Star), R(11),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(13),
B(Ldar), R(11),
B(PushContext), R(2),
B(LdaContextSlot), R(1), U8(9), U8(0),
B(Star), R(14),
B(Star), R(12),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(14), U8(15),
B(TestEqualStrict), R(12), U8(15),
B(JumpIfFalse), U8(8),
B(LdaSmi), I8(1),
B(StaContextSlot), R(1), U8(9), U8(0),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(14),
B(CallRuntime), U16(Runtime::kReThrow), R(14), U8(1),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kReThrow), R(12), U8(1),
B(PopContext), R(2),
B(LdaSmi), I8(-1),
B(Star), R(10),
B(Star), R(8),
B(Jump), U8(7),
B(Star), R(11),
B(Star), R(9),
B(LdaZero),
B(Star), R(10),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(12),
B(Star), R(10),
B(LdaContextSlot), R(1), U8(9), U8(0),
B(Star), R(13),
B(Star), R(11),
B(LdaZero),
B(TestEqualStrict), R(13), U8(16),
B(TestEqualStrict), R(11), U8(16),
B(JumpIfTrue), U8(150),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(9), U8(17),
B(Star), R(11),
B(LdaNamedProperty), R(11), U8(9), U8(17),
B(StaContextSlot), R(1), U8(11), U8(0),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(127),
B(LdaContextSlot), R(1), U8(9), U8(0),
B(Star), R(13),
B(Star), R(11),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(13), U8(20),
B(TestEqualStrict), R(11), U8(20),
B(JumpIfFalse), U8(69),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(130),
B(Star), R(13),
B(Star), R(11),
B(LdaConstant), U8(10),
B(Star), R(14),
B(CallRuntime), U16(Runtime::kNewTypeError), R(13), U8(2),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(Throw),
B(Mov), R(context), R(13),
B(Mov), R(context), R(11),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(Star), R(14),
B(Star), R(12),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(15),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(14), U8(2),
B(Jump), U8(20),
B(Star), R(14),
B(Ldar), R(closure),
B(CreateCatchContext), R(14), U8(7), U8(11),
B(Star), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
B(Jump), U8(20),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(7), U8(11),
B(Star), R(11),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(13),
B(Ldar), R(11),
B(PushContext), R(2),
B(PopContext), R(2),
B(Jump), U8(47),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(Star), R(13),
B(Star), R(11),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(14),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(13), U8(2),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
B(StaContextSlot), R(1), U8(12), U8(0),
B(LdaContextSlot), R(1), U8(12), U8(0),
B(Star), R(13),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(13), U8(1),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(11), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(13),
B(LdaContextSlot), R(1), U8(12), U8(0),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(13), U8(1),
B(Ldar), R(12),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(Ldar), R(10),
B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(10),
B(TestEqualStrictNoFeedback), R(8),
B(JumpIfTrue), U8(4),
B(Jump), U8(9),
B(PopContext), R(1),
B(PopContext), R(1),
B(Ldar), R(11),
B(Ldar), R(9),
B(ReThrow),
B(PopContext), R(1),
B(LdaUndefined),
B(Star), R(10),
B(Star), R(8),
B(LdaCurrentContextSlot), U8(13),
B(Star), R(11),
B(Star), R(9),
B(LdaUndefined),
B(Star), R(12),
B(CallJSRuntime), U8(%promise_resolve), R(10), U8(3),
B(Star), R(10),
B(CallJSRuntime), U8(%promise_resolve), R(8), U8(3),
B(LdaCurrentContextSlot), U8(13),
B(Star), R(7),
B(Star), R(5),
B(LdaZero),
B(Star), R(6),
B(Star), R(4),
B(Jump), U8(68),
B(Jump), U8(54),
B(Star), R(10),
B(Star), R(8),
B(Ldar), R(closure),
B(CreateCatchContext), R(10), U8(7), U8(12),
B(Star), R(9),
B(CreateCatchContext), R(8), U8(7), U8(12),
B(Star), R(7),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(9),
B(Ldar), R(7),
B(PushContext), R(1),
B(LdaUndefined),
B(Star), R(10),
B(Star), R(8),
B(LdaContextSlot), R(1), U8(13), U8(0),
B(Star), R(11),
B(Star), R(9),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(12),
B(Star), R(10),
B(LdaFalse),
B(Star), R(13),
B(CallJSRuntime), U8(%promise_internal_reject), R(10), U8(4),
B(Star), R(11),
B(CallJSRuntime), U8(%promise_internal_reject), R(8), U8(4),
B(LdaContextSlot), R(1), U8(13), U8(0),
B(PopContext), R(1),
B(PopContext), R(1),
B(Star), R(7),
B(Star), R(5),
B(LdaSmi), I8(1),
B(Star), R(6),
B(Star), R(4),
B(Jump), U8(14),
B(LdaSmi), I8(-1),
B(Star), R(6),
B(Star), R(4),
B(Jump), U8(8),
B(Star), R(7),
B(Star), R(5),
B(LdaSmi), I8(2),
B(Star), R(6),
B(Star), R(4),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(8),
B(Star), R(6),
B(LdaUndefined),
B(Star), R(9),
B(Star), R(7),
B(LdaCurrentContextSlot), U8(13),
B(Star), R(10),
B(CallJSRuntime), U8(%async_function_promise_release), R(9), U8(2),
B(Ldar), R(8),
B(Star), R(8),
B(CallJSRuntime), U8(%async_function_promise_release), R(7), U8(2),
B(Ldar), R(6),
B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(6),
B(TestEqualStrictNoFeedback), R(4),
B(JumpIfTrue), U8(16),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(6),
B(TestEqualStrictNoFeedback), R(4),
B(JumpIfTrue), U8(13),
B(LdaSmi), I8(2),
B(TestEqualStrictNoFeedback), R(6),
B(TestEqualStrictNoFeedback), R(4),
B(JumpIfTrue), U8(10),
B(Jump), U8(11),
B(Ldar), R(7),
B(Ldar), R(5),
/* 60 S> */ B(Return),
B(Ldar), R(7),
B(Ldar), R(5),
/* 60 S> */ B(Return),
B(Ldar), R(7),
B(Ldar), R(5),
B(ReThrow),
B(LdaUndefined),
/* 60 S> */ B(Return),
@ -1570,11 +1551,11 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[61, 553, 559],
[64, 499, 501],
[81, 282, 288],
[84, 234, 236],
[374, 390, 392],
[21, 513, 519],
[24, 459, 461],
[41, 242, 248],
[44, 194, 196],
[334, 350, 352],
]
---
@ -1589,14 +1570,12 @@ parameter count: 2
bytecode array length: 765
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(4),
B(ResumeGenerator), R(new_target),
B(Star), R(3),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(98),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
@ -1618,7 +1597,7 @@ bytecodes: [
B(Mov), R(context), R(7),
B(Mov), R(context), R(8),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(CreateBlockContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -1628,24 +1607,23 @@ bytecodes: [
B(Mov), R(context), R(12),
/* 40 S> */ B(LdaImmutableContextSlot), R(1), U8(4), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(1), U8(3),
B(LdaNamedProperty), R(13), U8(2), U8(3),
B(Star), R(14),
B(CallProperty0), R(14), R(13), U8(5),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
/* 40 E> */ B(StaContextSlot), R(1), U8(9), U8(0),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(3), U8(1), I8(0),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(16),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(157),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(79),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kAbort), R(13), U8(1),
/* 37 S> */ B(LdaContextSlot), R(1), U8(9), U8(0),
B(Star), R(14),
B(LdaNamedProperty), R(14), U8(2), U8(9),
B(LdaNamedProperty), R(14), U8(4), U8(9),
B(Star), R(13),
/* 37 E> */ B(CallProperty0), R(13), R(14), U8(7),
/* 37 E> */ B(StaContextSlot), R(1), U8(10), U8(0),
@ -1658,11 +1636,11 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(13), U8(1),
B(LdaContextSlot), R(1), U8(10), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(3), U8(11),
B(LdaNamedProperty), R(13), U8(5), U8(11),
B(JumpIfToBooleanTrue), U8(167),
B(LdaContextSlot), R(1), U8(10), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(4), U8(13),
B(LdaNamedProperty), R(13), U8(6), U8(13),
B(StaContextSlot), R(1), U8(12), U8(0),
B(LdaSmi), I8(2),
B(StaContextSlot), R(1), U8(11), U8(0),
@ -1670,7 +1648,7 @@ bytecodes: [
B(StaContextSlot), R(1), U8(8), U8(0),
/* 26 E> */ B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(5),
B(CreateBlockContext), U8(7),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -1726,11 +1704,11 @@ bytecodes: [
B(PopContext), R(2),
B(LdaZero),
B(StaContextSlot), R(1), U8(11), U8(0),
B(JumpLoop), U8(234), I8(0),
B(JumpLoop), U8(235), I8(0),
B(Jump), U8(48),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(6), U8(7),
B(CreateCatchContext), R(13), U8(8), U8(9),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
@ -1763,7 +1741,7 @@ bytecodes: [
B(JumpIfTrue), U8(150),
B(LdaContextSlot), R(1), U8(9), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(8), U8(17),
B(LdaNamedProperty), R(12), U8(10), U8(17),
B(StaContextSlot), R(1), U8(13), U8(0),
B(LdaContextSlot), R(1), U8(13), U8(0),
B(TestUndetectable),
@ -1780,7 +1758,7 @@ bytecodes: [
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(130),
B(Star), R(12),
B(LdaConstant), U8(9),
B(LdaConstant), U8(11),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kNewTypeError), R(12), U8(2),
B(Throw),
@ -1793,7 +1771,7 @@ bytecodes: [
B(Jump), U8(20),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(6), U8(10),
B(CreateCatchContext), R(13), U8(8), U8(12),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
@ -1852,7 +1830,7 @@ bytecodes: [
B(Jump), U8(54),
B(Star), R(9),
B(Ldar), R(closure),
B(CreateCatchContext), R(9), U8(6), U8(11),
B(CreateCatchContext), R(9), U8(8), U8(13),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
@ -1915,8 +1893,10 @@ bytecodes: [
/* 54 S> */ B(Return),
]
constant pool: [
Smi [100],
FIXED_ARRAY_TYPE,
SYMBOL_TYPE,
Smi [165],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
@ -1929,10 +1909,10 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[66, 696, 702],
[69, 642, 644],
[86, 401, 407],
[89, 353, 355],
[65, 696, 702],
[68, 642, 644],
[85, 401, 407],
[88, 353, 355],
[494, 510, 512],
]

View File

@ -13,17 +13,15 @@ snippet: "
"
frame size: 12
parameter count: 1
bytecode array length: 193
bytecode array length: 192
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(50),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
@ -110,9 +108,10 @@ bytecodes: [
/* 16 S> */ B(Return),
]
constant pool: [
Smi [52],
]
handlers: [
[53, 135, 141],
[52, 134, 140],
]
---
@ -122,20 +121,15 @@ snippet: "
"
frame size: 12
parameter count: 1
bytecode array length: 283
bytecode array length: 276
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(33),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(56),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(124),
B(SwitchOnSmiNoFeedback), U8(0), U8(2), I8(0),
B(LdaSmi), I8(79),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
@ -261,9 +255,11 @@ bytecodes: [
/* 25 S> */ B(Return),
]
constant pool: [
Smi [52],
Smi [126],
]
handlers: [
[59, 216, 222],
[52, 209, 215],
]
---
@ -273,20 +269,15 @@ snippet: "
"
frame size: 18
parameter count: 1
bytecode array length: 743
bytecode array length: 736
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(33),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(4),
B(ResumeGenerator), R(new_target),
B(Star), R(3),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(56),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(146),
B(SwitchOnSmiNoFeedback), U8(0), U8(2), I8(0),
B(LdaSmi), I8(79),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
@ -327,11 +318,11 @@ bytecodes: [
B(Star), R(6),
B(LdaZero),
B(Star), R(5),
B(JumpConstant), U8(12),
B(JumpConstant), U8(15),
B(Ldar), R(10),
/* 11 E> */ B(Throw),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(CreateBlockContext), U8(2),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -339,26 +330,25 @@ bytecodes: [
B(StaContextSlot), R(1), U8(8), U8(0),
B(Mov), R(context), R(10),
B(Mov), R(context), R(11),
/* 30 S> */ B(CreateArrayLiteral), U8(1), U8(3), U8(17),
/* 30 S> */ B(CreateArrayLiteral), U8(3), U8(3), U8(17),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(2), U8(4),
B(LdaNamedProperty), R(12), U8(4), U8(4),
B(Star), R(13),
B(CallProperty0), R(13), R(12), U8(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
/* 30 E> */ B(StaContextSlot), R(1), U8(6), U8(0),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(5), U8(1), I8(1),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(17),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(134),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(79),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kAbort), R(12), U8(1),
/* 27 S> */ B(LdaContextSlot), R(1), U8(6), U8(0),
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(3), U8(10),
B(LdaNamedProperty), R(13), U8(6), U8(10),
B(Star), R(12),
/* 27 E> */ B(CallProperty0), R(12), R(13), U8(8),
/* 27 E> */ B(StaContextSlot), R(1), U8(7), U8(0),
@ -371,11 +361,11 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(4), U8(12),
B(LdaNamedProperty), R(12), U8(7), U8(12),
B(JumpIfToBooleanTrue), U8(144),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(5), U8(14),
B(LdaNamedProperty), R(12), U8(8), U8(14),
B(StaContextSlot), R(1), U8(9), U8(0),
B(LdaSmi), I8(2),
B(StaContextSlot), R(1), U8(8), U8(0),
@ -383,7 +373,7 @@ bytecodes: [
B(StaContextSlot), R(1), U8(5), U8(0),
/* 16 E> */ B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(6),
B(CreateBlockContext), U8(9),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -436,7 +426,7 @@ bytecodes: [
B(Jump), U8(44),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(7), U8(8),
B(CreateCatchContext), R(12), U8(10), U8(11),
B(PushContext), R(2),
B(Star), R(11),
B(LdaContextSlot), R(1), U8(8), U8(0),
@ -466,7 +456,7 @@ bytecodes: [
B(JumpIfTrue), U8(150),
B(LdaContextSlot), R(1), U8(6), U8(0),
B(Star), R(11),
B(LdaNamedProperty), R(11), U8(9), U8(18),
B(LdaNamedProperty), R(11), U8(12), U8(18),
B(StaContextSlot), R(1), U8(10), U8(0),
B(LdaContextSlot), R(1), U8(10), U8(0),
B(TestUndetectable),
@ -483,7 +473,7 @@ bytecodes: [
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(130),
B(Star), R(11),
B(LdaConstant), U8(10),
B(LdaConstant), U8(13),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(Throw),
@ -496,7 +486,7 @@ bytecodes: [
B(Jump), U8(20),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(7), U8(11),
B(CreateCatchContext), R(12), U8(10), U8(14),
B(Star), R(11),
B(LdaTheHole),
B(SetPendingMessage),
@ -593,9 +583,12 @@ bytecodes: [
/* 44 S> */ B(Return),
]
constant pool: [
Smi [52],
Smi [148],
FIXED_ARRAY_TYPE,
TUPLE2_TYPE,
SYMBOL_TYPE,
Smi [142],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
@ -608,9 +601,9 @@ constant pool: [
Smi [561],
]
handlers: [
[59, 667, 673],
[140, 429, 435],
[143, 385, 387],
[522, 538, 540],
[52, 660, 666],
[133, 422, 428],
[136, 378, 380],
[515, 531, 533],
]

View File

@ -13,23 +13,21 @@ snippet: "
"
frame size: 9
parameter count: 2
bytecode array length: 137
bytecode array length: 136
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(60),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(5),
B(Mov), R(arg0), R(3),
B(Mov), R(closure), R(4),
@ -77,6 +75,7 @@ bytecodes: [
/* 13 S> */ B(Return),
]
constant pool: [
Smi [62],
FIXED_ARRAY_TYPE,
]
handlers: [
@ -88,23 +87,21 @@ snippet: "
"
frame size: 9
parameter count: 2
bytecode array length: 137
bytecode array length: 136
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(60),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(5),
B(Mov), R(arg0), R(3),
B(Mov), R(closure), R(4),
@ -152,6 +149,7 @@ bytecodes: [
/* 24 S> */ B(Return),
]
constant pool: [
Smi [62],
FIXED_ARRAY_TYPE,
]
handlers: [
@ -165,23 +163,21 @@ snippet: "
"
frame size: 10
parameter count: 2
bytecode array length: 199
bytecode array length: 198
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(3),
B(ResumeGenerator), R(new_target),
B(Star), R(2),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(2),
B(JumpIfTrue), U8(60),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(2),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(6),
B(Mov), R(arg0), R(4),
B(Mov), R(closure), R(5),
@ -221,7 +217,7 @@ bytecodes: [
/* 0 E> */ B(Throw),
/* 32 S> */ B(LdaModuleVariable), I8(-1), U8(0),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(1),
B(LdaConstant), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1),
B(Star), R(4),
@ -229,7 +225,7 @@ bytecodes: [
B(Star), R(5),
/* 32 E> */ B(CallUndefinedReceiver1), R(4), R(5), U8(3),
B(Ldar), R(closure),
B(CreateBlockContext), U8(2),
B(CreateBlockContext), U8(3),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -237,7 +233,7 @@ bytecodes: [
/* 47 E> */ B(StaCurrentContextSlot), U8(4),
/* 52 S> */ B(LdaModuleVariable), I8(-1), U8(1),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(1),
B(LdaConstant), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1),
B(Star), R(4),
@ -254,6 +250,7 @@ bytecodes: [
/* 64 S> */ B(Return),
]
constant pool: [
Smi [62],
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["goo"],
FIXED_ARRAY_TYPE,
@ -269,23 +266,21 @@ snippet: "
"
frame size: 10
parameter count: 2
bytecode array length: 179
bytecode array length: 178
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(3),
B(ResumeGenerator), R(new_target),
B(Star), R(2),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(2),
B(JumpIfTrue), U8(60),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(2),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(6),
B(Mov), R(arg0), R(4),
B(Mov), R(closure), R(5),
@ -329,7 +324,7 @@ bytecodes: [
B(Inc), U8(3),
/* 24 E> */ B(StaModuleVariable), I8(1), U8(0),
B(Ldar), R(closure),
B(CreateBlockContext), U8(1),
B(CreateBlockContext), U8(2),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -351,6 +346,7 @@ bytecodes: [
/* 49 S> */ B(Return),
]
constant pool: [
Smi [62],
FIXED_ARRAY_TYPE,
FIXED_ARRAY_TYPE,
]
@ -365,23 +361,21 @@ snippet: "
"
frame size: 10
parameter count: 2
bytecode array length: 183
bytecode array length: 182
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(3),
B(ResumeGenerator), R(new_target),
B(Star), R(2),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(2),
B(JumpIfTrue), U8(64),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(2),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(6),
B(Mov), R(arg0), R(4),
B(Mov), R(closure), R(5),
@ -427,7 +421,7 @@ bytecodes: [
B(Inc), U8(3),
/* 24 E> */ B(StaModuleVariable), I8(1), U8(0),
B(Ldar), R(closure),
B(CreateBlockContext), U8(1),
B(CreateBlockContext), U8(2),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -449,6 +443,7 @@ bytecodes: [
/* 49 S> */ B(Return),
]
constant pool: [
Smi [66],
FIXED_ARRAY_TYPE,
FIXED_ARRAY_TYPE,
]
@ -463,23 +458,21 @@ snippet: "
"
frame size: 10
parameter count: 2
bytecode array length: 187
bytecode array length: 186
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(3),
B(ResumeGenerator), R(new_target),
B(Star), R(2),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(2),
B(JumpIfTrue), U8(64),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(2),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(6),
B(Mov), R(arg0), R(4),
B(Mov), R(closure), R(5),
@ -525,7 +518,7 @@ bytecodes: [
B(Inc), U8(3),
/* 26 E> */ B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), U8(0),
B(Ldar), R(closure),
B(CreateBlockContext), U8(1),
B(CreateBlockContext), U8(2),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -547,6 +540,7 @@ bytecodes: [
/* 51 S> */ B(Return),
]
constant pool: [
Smi [66],
FIXED_ARRAY_TYPE,
FIXED_ARRAY_TYPE,
]
@ -559,23 +553,21 @@ snippet: "
"
frame size: 9
parameter count: 2
bytecode array length: 148
bytecode array length: 147
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(64),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(5),
B(Mov), R(arg0), R(3),
B(Mov), R(closure), R(4),
@ -617,7 +609,7 @@ bytecodes: [
/* 0 E> */ B(Throw),
B(Ldar), R(5),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(1), U8(3), U8(0),
B(CreateClosure), U8(2), U8(3), U8(0),
B(StaModuleVariable), I8(1), U8(0),
B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
@ -627,6 +619,7 @@ bytecodes: [
/* 32 S> */ B(Return),
]
constant pool: [
Smi [66],
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
]
@ -639,23 +632,21 @@ snippet: "
"
frame size: 9
parameter count: 2
bytecode array length: 181
bytecode array length: 180
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(64),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(5),
B(Mov), R(arg0), R(3),
B(Mov), R(closure), R(4),
@ -697,7 +688,7 @@ bytecodes: [
/* 0 E> */ B(Throw),
B(Ldar), R(5),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(1), U8(3), U8(0),
B(CreateClosure), U8(2), U8(3), U8(0),
B(Star), R(3),
B(LdaTheHole),
B(Star), R(4),
@ -719,6 +710,7 @@ bytecodes: [
/* 26 S> */ B(Return),
]
constant pool: [
Smi [66],
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
]
@ -731,23 +723,21 @@ snippet: "
"
frame size: 9
parameter count: 2
bytecode array length: 137
bytecode array length: 136
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(60),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(5),
B(Mov), R(arg0), R(3),
B(Mov), R(closure), R(4),
@ -795,6 +785,7 @@ bytecodes: [
/* 30 S> */ B(Return),
]
constant pool: [
Smi [62],
FIXED_ARRAY_TYPE,
]
handlers: [
@ -806,23 +797,21 @@ snippet: "
"
frame size: 9
parameter count: 2
bytecode array length: 137
bytecode array length: 136
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(60),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(5),
B(Mov), R(arg0), R(3),
B(Mov), R(closure), R(4),
@ -870,6 +859,7 @@ bytecodes: [
/* 19 S> */ B(Return),
]
constant pool: [
Smi [62],
FIXED_ARRAY_TYPE,
]
handlers: [
@ -882,23 +872,21 @@ snippet: "
"
frame size: 9
parameter count: 2
bytecode array length: 175
bytecode array length: 174
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(70),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
B(LdaConstant), U8(1),
B(Star), R(5),
B(Mov), R(arg0), R(3),
B(Mov), R(closure), R(4),
@ -942,13 +930,13 @@ bytecodes: [
/* 0 E> */ B(Throw),
/* 27 S> */ B(LdaImmutableCurrentContextSlot), U8(5),
B(Star), R(4),
/* 30 E> */ B(LdaNamedProperty), R(4), U8(1), U8(5),
/* 30 E> */ B(LdaNamedProperty), R(4), U8(2), U8(5),
B(Star), R(3),
B(LdaImmutableCurrentContextSlot), U8(5),
B(Star), R(5),
B(LdaImmutableCurrentContextSlot), U8(5),
B(Star), R(6),
/* 41 E> */ B(LdaNamedProperty), R(6), U8(2), U8(7),
/* 41 E> */ B(LdaNamedProperty), R(6), U8(3), U8(7),
B(Star), R(6),
/* 31 E> */ B(CallProperty2), R(3), R(4), R(5), R(6), U8(3),
B(StaCurrentContextSlot), U8(6),
@ -960,6 +948,7 @@ bytecodes: [
/* 45 S> */ B(Return),
]
constant pool: [
Smi [72],
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["f"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["x"],

View File

@ -273,17 +273,15 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 351
bytecode array length: 350
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(5),
B(ResumeGenerator), R(new_target),
B(Star), R(4),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(4),
B(JumpIfTrue), U8(50),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kAbort), R(6), U8(1),
@ -328,7 +326,7 @@ bytecodes: [
B(Ldar), R(11),
/* 11 E> */ B(Throw),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(CreateBlockContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -340,7 +338,7 @@ bytecodes: [
B(StaContextSlot), R(1), U8(6), U8(0),
B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(1),
B(CreateBlockContext), U8(2),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -374,7 +372,7 @@ bytecodes: [
B(JumpIfFalse), U8(34),
/* 18 E> */ B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(2),
B(CreateBlockContext), U8(3),
B(PushContext), R(3),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -439,12 +437,13 @@ bytecodes: [
/* 62 S> */ B(Return),
]
constant pool: [
Smi [52],
FIXED_ARRAY_TYPE,
FIXED_ARRAY_TYPE,
FIXED_ARRAY_TYPE,
]
handlers: [
[53, 293, 299],
[52, 292, 298],
]
---
@ -456,20 +455,15 @@ snippet: "
"
frame size: 14
parameter count: 1
bytecode array length: 476
bytecode array length: 469
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(33),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(4),
B(ResumeGenerator), R(new_target),
B(Star), R(3),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(56),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(123),
B(SwitchOnSmiNoFeedback), U8(0), U8(2), I8(0),
B(LdaSmi), I8(79),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
@ -510,11 +504,11 @@ bytecodes: [
B(Star), R(6),
B(LdaZero),
B(Star), R(5),
B(JumpConstant), U8(2),
B(JumpConstant), U8(6),
B(Ldar), R(10),
/* 11 E> */ B(Throw),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(CreateBlockContext), U8(2),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -524,18 +518,17 @@ bytecodes: [
/* 54 E> */ B(StaContextSlot), R(1), U8(5), U8(0),
B(LdaSmi), I8(1),
B(StaContextSlot), R(1), U8(6), U8(0),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(3), U8(1), I8(1),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(17),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(76),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(79),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kAbort), R(8), U8(1),
B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(1),
B(CreateBlockContext), U8(4),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -562,12 +555,11 @@ bytecodes: [
B(Jump), U8(6),
B(PopContext), R(2),
B(Jump), U8(158),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(5), U8(1), I8(1),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(17),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(52),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(79),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kAbort), R(8), U8(1),
@ -678,12 +670,16 @@ bytecodes: [
/* 56 S> */ B(Return),
]
constant pool: [
Smi [52],
Smi [125],
FIXED_ARRAY_TYPE,
Smi [84],
FIXED_ARRAY_TYPE,
Smi [60],
Smi [303],
]
handlers: [
[59, 409, 415],
[52, 402, 408],
]
---
@ -693,34 +689,19 @@ snippet: "
}
f();
"
frame size: 14
frame size: 12
parameter count: 1
bytecode array length: 355
bytecode array length: 315
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(22),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(5),
B(ResumeGenerator), R(new_target),
B(Star), R(4),
B(LdaSmi), I8(79),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kAbort), R(6), U8(1),
B(LdaSmi), I8(-2),
B(Star), R(4),
B(CreateFunctionContext), U8(5),
B(PushContext), R(0),
B(Mov), R(closure), R(6),
B(Mov), R(this), R(7),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(6), U8(2),
B(StaCurrentContextSlot), U8(4),
/* 16 E> */ B(StackCheck),
B(LdaUndefined),
B(Star), R(6),
B(CallJSRuntime), U8(%async_function_promise_create), R(6), U8(1),
B(Star), R(4),
B(CallJSRuntime), U8(%async_function_promise_create), R(4), U8(1),
B(StaCurrentContextSlot), U8(8),
B(Mov), R(context), R(8),
B(Mov), R(context), R(9),
B(Mov), R(context), R(6),
B(Mov), R(context), R(7),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(PushContext), R(1),
@ -741,9 +722,9 @@ bytecodes: [
B(LdaContextSlot), R(1), U8(5), U8(0),
B(StaCurrentContextSlot), U8(4),
B(LdaContextSlot), R(1), U8(6), U8(0),
B(Star), R(10),
B(Star), R(8),
B(LdaSmi), I8(1),
B(TestEqual), R(10), U8(3),
B(TestEqual), R(8), U8(3),
B(JumpIfFalse), U8(9),
B(LdaZero),
B(StaContextSlot), R(1), U8(6), U8(0),
@ -754,17 +735,17 @@ bytecodes: [
B(LdaSmi), I8(1),
B(StaContextSlot), R(1), U8(7), U8(0),
/* 41 S> */ B(LdaCurrentContextSlot), U8(4),
B(Star), R(10),
B(Star), R(8),
B(LdaSmi), I8(10),
/* 41 E> */ B(TestLessThan), R(10), U8(5),
/* 41 E> */ B(TestLessThan), R(8), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(6),
B(PopContext), R(2),
B(Jump), U8(69),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(10),
B(Star), R(8),
B(LdaSmi), I8(1),
B(TestEqual), R(10), U8(6),
B(TestEqual), R(8), U8(6),
B(JumpIfFalse), U8(34),
/* 23 E> */ B(StackCheck),
B(Ldar), R(closure),
@ -781,9 +762,9 @@ bytecodes: [
/* 65 E> */ B(StaContextSlot), R(1), U8(5), U8(0),
B(JumpLoop), U8(42), I8(1),
B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(10),
B(Star), R(8),
B(LdaSmi), I8(1),
B(TestEqual), R(10), U8(7),
B(TestEqual), R(8), U8(7),
B(JumpIfFalse), U8(6),
B(PopContext), R(2),
B(Jump), U8(7),
@ -791,73 +772,73 @@ bytecodes: [
B(JumpLoop), U8(129), I8(0),
B(PopContext), R(1),
B(LdaUndefined),
B(Star), R(10),
B(Star), R(8),
B(LdaCurrentContextSlot), U8(8),
B(Star), R(11),
B(Star), R(9),
B(LdaUndefined),
B(Star), R(12),
B(CallJSRuntime), U8(%promise_resolve), R(10), U8(3),
B(Star), R(10),
B(CallJSRuntime), U8(%promise_resolve), R(8), U8(3),
B(LdaCurrentContextSlot), U8(8),
B(Star), R(7),
B(Star), R(5),
B(LdaZero),
B(Star), R(6),
B(Star), R(4),
B(Jump), U8(68),
B(Jump), U8(54),
B(Star), R(10),
B(Star), R(8),
B(Ldar), R(closure),
B(CreateCatchContext), R(10), U8(3), U8(4),
B(Star), R(9),
B(CreateCatchContext), R(8), U8(3), U8(4),
B(Star), R(7),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(9),
B(Ldar), R(7),
B(PushContext), R(1),
B(LdaUndefined),
B(Star), R(10),
B(Star), R(8),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(Star), R(11),
B(Star), R(9),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(12),
B(Star), R(10),
B(LdaFalse),
B(Star), R(13),
B(CallJSRuntime), U8(%promise_internal_reject), R(10), U8(4),
B(Star), R(11),
B(CallJSRuntime), U8(%promise_internal_reject), R(8), U8(4),
B(LdaContextSlot), R(1), U8(8), U8(0),
B(PopContext), R(1),
B(PopContext), R(1),
B(Star), R(7),
B(Star), R(5),
B(LdaSmi), I8(1),
B(Star), R(6),
B(Star), R(4),
B(Jump), U8(14),
B(LdaSmi), I8(-1),
B(Star), R(6),
B(Star), R(4),
B(Jump), U8(8),
B(Star), R(7),
B(Star), R(5),
B(LdaSmi), I8(2),
B(Star), R(6),
B(Star), R(4),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(8),
B(Star), R(6),
B(LdaUndefined),
B(Star), R(9),
B(Star), R(7),
B(LdaCurrentContextSlot), U8(8),
B(Star), R(10),
B(CallJSRuntime), U8(%async_function_promise_release), R(9), U8(2),
B(Ldar), R(8),
B(Star), R(8),
B(CallJSRuntime), U8(%async_function_promise_release), R(7), U8(2),
B(Ldar), R(6),
B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(6),
B(TestEqualStrictNoFeedback), R(4),
B(JumpIfTrue), U8(16),
B(LdaSmi), I8(1),
B(TestEqualStrictNoFeedback), R(6),
B(TestEqualStrictNoFeedback), R(4),
B(JumpIfTrue), U8(13),
B(LdaSmi), I8(2),
B(TestEqualStrictNoFeedback), R(6),
B(TestEqualStrictNoFeedback), R(4),
B(JumpIfTrue), U8(10),
B(Jump), U8(11),
B(Ldar), R(7),
B(Ldar), R(5),
/* 67 S> */ B(Return),
B(Ldar), R(7),
B(Ldar), R(5),
/* 67 S> */ B(Return),
B(Ldar), R(7),
B(Ldar), R(5),
B(ReThrow),
B(LdaUndefined),
/* 67 S> */ B(Return),
@ -870,8 +851,8 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[57, 295, 301],
[60, 241, 243],
[17, 255, 261],
[20, 201, 203],
]
---
@ -883,17 +864,15 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 507
bytecode array length: 508
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(27),
B(JumpIfUndefined), U8(26),
B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
B(PushContext), R(4),
B(ResumeGenerator), R(new_target),
B(Star), R(3),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(71),
B(SwitchOnSmiNoFeedback), U8(0), U8(1), I8(0),
B(LdaSmi), I8(79),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
@ -913,7 +892,7 @@ bytecodes: [
B(Mov), R(context), R(7),
B(Mov), R(context), R(8),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(CreateBlockContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -923,18 +902,17 @@ bytecodes: [
/* 59 E> */ B(StaContextSlot), R(1), U8(7), U8(0),
B(LdaSmi), I8(1),
B(StaContextSlot), R(1), U8(8), U8(0),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(2), U8(1), I8(0),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(16),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(76),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(79),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kAbort), R(9), U8(1),
B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(1),
B(CreateBlockContext), U8(3),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
@ -960,13 +938,12 @@ bytecodes: [
B(JumpIfFalse), U8(4),
B(Jump), U8(6),
B(PopContext), R(2),
B(Jump), U8(186),
B(Jump), U8(187),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(4), U8(1), I8(0),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(16),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(3),
B(JumpIfTrue), U8(75),
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(79),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kAbort), R(9), U8(1),
@ -1027,7 +1004,7 @@ bytecodes: [
B(StaContextSlot), R(1), U8(9), U8(0),
B(LdaCurrentContextSlot), U8(4),
/* 59 E> */ B(StaContextSlot), R(1), U8(7), U8(0),
B(JumpLoop), U8(156), I8(1),
B(JumpLoop), U8(157), I8(1),
B(LdaContextSlot), R(1), U8(9), U8(0),
B(Star), R(9),
B(LdaSmi), I8(1),
@ -1036,7 +1013,7 @@ bytecodes: [
B(PopContext), R(2),
B(Jump), U8(10),
B(PopContext), R(2),
B(Wide), B(JumpLoop), U16(264), I16(0),
B(Wide), B(JumpLoop), U16(266), I16(0),
B(PopContext), R(1),
B(LdaUndefined),
B(Star), R(9),
@ -1053,7 +1030,7 @@ bytecodes: [
B(Jump), U8(54),
B(Star), R(9),
B(Ldar), R(closure),
B(CreateCatchContext), R(9), U8(2), U8(3),
B(CreateCatchContext), R(9), U8(5), U8(6),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
@ -1116,13 +1093,16 @@ bytecodes: [
/* 61 S> */ B(Return),
]
constant pool: [
Smi [73],
FIXED_ARRAY_TYPE,
Smi [84],
FIXED_ARRAY_TYPE,
Smi [83],
ONE_BYTE_INTERNALIZED_STRING_TYPE [".catch"],
FIXED_ARRAY_TYPE,
]
handlers: [
[62, 438, 444],
[65, 384, 386],
[61, 439, 445],
[64, 385, 387],
]

View File

@ -235,9 +235,10 @@ TEST_F(BytecodeAnalysisTest, SimpleLoop) {
builder.StoreAccumulatorInRegister(reg_0);
expected_liveness.emplace_back("..LL", "L.LL");
interpreter::LoopBuilder loop_builder(&builder);
loop_builder.LoopHeader();
{
interpreter::LoopBuilder loop_builder(&builder);
loop_builder.LoopHeader();
builder.JumpIfTrue(ToBooleanMode::kConvertToBoolean,
loop_builder.break_labels()->New());
expected_liveness.emplace_back("L.LL", "L.L.");
@ -252,7 +253,6 @@ TEST_F(BytecodeAnalysisTest, SimpleLoop) {
loop_builder.JumpToHeader(0);
expected_liveness.emplace_back("L.LL", "L.LL");
}
loop_builder.EndLoop();
builder.LoadAccumulatorWithRegister(reg_2);
expected_liveness.emplace_back("..L.", "...L");
@ -321,9 +321,10 @@ TEST_F(BytecodeAnalysisTest, DiamondInLoop) {
builder.StoreAccumulatorInRegister(reg_0);
expected_liveness.emplace_back("...L", "L..L");
interpreter::LoopBuilder loop_builder(&builder);
loop_builder.LoopHeader();
{
interpreter::LoopBuilder loop_builder(&builder);
loop_builder.LoopHeader();
builder.JumpIfTrue(ToBooleanMode::kConvertToBoolean,
loop_builder.break_labels()->New());
expected_liveness.emplace_back("L..L", "L..L");
@ -350,7 +351,6 @@ TEST_F(BytecodeAnalysisTest, DiamondInLoop) {
loop_builder.JumpToHeader(0);
expected_liveness.emplace_back("L..L", "L..L");
}
loop_builder.EndLoop();
builder.Return();
expected_liveness.emplace_back("...L", "....");
@ -370,9 +370,10 @@ TEST_F(BytecodeAnalysisTest, KillingLoopInsideLoop) {
builder.StoreAccumulatorInRegister(reg_0);
expected_liveness.emplace_back(".L.L", "LL..");
interpreter::LoopBuilder loop_builder(&builder);
loop_builder.LoopHeader();
{
interpreter::LoopBuilder loop_builder(&builder);
loop_builder.LoopHeader();
builder.LoadAccumulatorWithRegister(reg_0);
expected_liveness.emplace_back("LL..", ".L..");
@ -383,9 +384,10 @@ TEST_F(BytecodeAnalysisTest, KillingLoopInsideLoop) {
loop_builder.break_labels()->New());
expected_liveness.emplace_back(".L.L", ".L.L");
interpreter::LoopBuilder inner_loop_builder(&builder);
inner_loop_builder.LoopHeader();
{
interpreter::LoopBuilder inner_loop_builder(&builder);
inner_loop_builder.LoopHeader();
builder.StoreAccumulatorInRegister(reg_0);
expected_liveness.emplace_back(".L.L", "LL.L");
@ -397,13 +399,11 @@ TEST_F(BytecodeAnalysisTest, KillingLoopInsideLoop) {
inner_loop_builder.JumpToHeader(1);
expected_liveness.emplace_back(".L.L", ".L.L");
}
inner_loop_builder.EndLoop();
loop_builder.BindContinueTarget();
loop_builder.JumpToHeader(0);
expected_liveness.emplace_back("LL..", "LL..");
}
loop_builder.EndLoop();
builder.Return();
expected_liveness.emplace_back("...L", "....");

View File

@ -7,6 +7,7 @@
#include "src/ast/scopes.h"
#include "src/interpreter/bytecode-array-builder.h"
#include "src/interpreter/bytecode-array-iterator.h"
#include "src/interpreter/bytecode-jump-table.h"
#include "src/interpreter/bytecode-label.h"
#include "src/interpreter/bytecode-register-allocator.h"
#include "src/objects-inl.h"
@ -278,6 +279,10 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.JumpIfJSReceiver(&end[10]);
}
// Emit Smi table switch bytecode.
BytecodeJumpTable* jump_table = builder.AllocateJumpTable(1, 0);
builder.SwitchOnSmiNoFeedback(jump_table).Bind(jump_table, 0);
// Emit set pending message bytecode.
builder.SetPendingMessage();