Commit 00d6f1f8 authored by danno's avatar danno Committed by Commit bot

[interpreter] Create custom call opcodes for specific argument counts

Specifically, add bytecodes for Call0, Call1, Call2, CallProperty0, CallProperty1,
and CallProperty2. Also share the bytecode handler code between between
equivalent CallX and CallPropertyX handlers.

Review-Url: https://codereview.chromium.org/2684993002
Cr-Commit-Position: refs/heads/master@{#43290}
parent 3e1db847
......@@ -1293,10 +1293,8 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
literal, Environment::kAttachFrameState);
}
Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
Node* callee,
interpreter::Register receiver,
size_t arity) {
Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister(
Node* callee, interpreter::Register receiver, size_t arity) {
Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity));
all[0] = callee;
all[1] = environment()->LookupRegister(receiver);
......@@ -1305,34 +1303,133 @@ Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
all[i] = environment()->LookupRegister(
interpreter::Register(receiver_index + i - 1));
}
Node* value = MakeNode(call_op, static_cast<int>(arity), all, false);
return value;
return all;
}
Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
Node* const* args,
size_t arg_count) {
return MakeNode(call_op, static_cast<int>(arg_count), args, false);
}
Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
Node* callee,
interpreter::Register receiver,
size_t arg_count) {
return ProcessCallArguments(
call_op, GetCallArgumentsFromRegister(callee, receiver, arg_count),
arg_count);
}
void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode,
ConvertReceiverMode receiver_hint) {
ConvertReceiverMode receiver_hint,
Node* const* args, size_t arg_count,
int slot_id) {
PrepareEagerCheckpoint();
Node* callee =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
// Slot index of 0 is used indicate no feedback slot is available. Assert
// the assumption that slot index 0 is never a valid feedback slot.
STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0);
int const slot_id = bytecode_iterator().GetIndexOperand(3);
VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
float const frequency = ComputeCallFrequency(slot_id);
const Operator* call = javascript()->Call(arg_count + 1, frequency, feedback,
const Operator* call = javascript()->Call(arg_count, frequency, feedback,
receiver_hint, tail_call_mode);
Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
Node* value = ProcessCallArguments(call, args, arg_count);
environment()->BindAccumulator(value, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::BuildCallVarArgs(TailCallMode tail_call_mode,
ConvertReceiverMode receiver_hint) {
Node* callee =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
int const slot_id = bytecode_iterator().GetIndexOperand(3);
BuildCall(tail_call_mode, receiver_hint,
GetCallArgumentsFromRegister(callee, receiver, arg_count + 1),
arg_count + 1, slot_id);
}
void BytecodeGraphBuilder::VisitCall() {
BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny);
BuildCallVarArgs(TailCallMode::kDisallow, ConvertReceiverMode::kAny);
}
void BytecodeGraphBuilder::VisitCall0() {
Node* callee =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* receiver =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
int const slot_id = bytecode_iterator().GetIndexOperand(2);
BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny,
{callee, receiver}, slot_id);
}
void BytecodeGraphBuilder::VisitCall1() {
Node* callee =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* receiver =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Node* arg0 =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
int const slot_id = bytecode_iterator().GetIndexOperand(3);
BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny,
{callee, receiver, arg0}, slot_id);
}
void BytecodeGraphBuilder::VisitCall2() {
Node* callee =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* receiver =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Node* arg0 =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
Node* arg1 =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
int const slot_id = bytecode_iterator().GetIndexOperand(4);
BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny,
{callee, receiver, arg0, arg1}, slot_id);
}
void BytecodeGraphBuilder::VisitCallProperty() {
BuildCallVarArgs(TailCallMode::kDisallow,
ConvertReceiverMode::kNotNullOrUndefined);
}
void BytecodeGraphBuilder::VisitCallProperty0() {
Node* callee =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* receiver =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
int const slot_id = bytecode_iterator().GetIndexOperand(2);
BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined,
{callee, receiver}, slot_id);
}
void BytecodeGraphBuilder::VisitCallProperty1() {
Node* callee =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* receiver =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Node* arg0 =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
int const slot_id = bytecode_iterator().GetIndexOperand(3);
BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined,
{callee, receiver, arg0}, slot_id);
}
void BytecodeGraphBuilder::VisitCallProperty2() {
Node* callee =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* receiver =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Node* arg0 =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
Node* arg1 =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
int const slot_id = bytecode_iterator().GetIndexOperand(4);
BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined,
{callee, receiver, arg0, arg1}, slot_id);
}
void BytecodeGraphBuilder::VisitCallWithSpread() {
......@@ -1348,16 +1445,12 @@ void BytecodeGraphBuilder::VisitCallWithSpread() {
environment()->BindAccumulator(value, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitCallProperty() {
BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined);
}
void BytecodeGraphBuilder::VisitTailCall() {
TailCallMode tail_call_mode =
bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled()
? TailCallMode::kAllow
: TailCallMode::kDisallow;
BuildCall(tail_call_mode, ConvertReceiverMode::kAny);
BuildCallVarArgs(tail_call_mode, ConvertReceiverMode::kAny);
}
void BytecodeGraphBuilder::VisitCallJSRuntime() {
......@@ -2247,7 +2340,8 @@ void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
}
Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
Node** value_inputs, bool incomplete) {
Node* const* value_inputs,
bool incomplete) {
DCHECK_EQ(op->ValueInputCount(), value_input_count);
bool has_context = OperatorProperties::HasContextInput(op);
......
......@@ -104,11 +104,16 @@ class BytecodeGraphBuilder {
// The main node creation chokepoint. Adds context, frame state, effect,
// and control dependencies depending on the operator.
Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
bool incomplete);
Node* MakeNode(const Operator* op, int value_input_count,
Node* const* value_inputs, bool incomplete);
Node** EnsureInputBufferSize(int size);
Node* const* GetCallArgumentsFromRegister(Node* callee,
interpreter::Register first_arg,
size_t arity);
Node* ProcessCallArguments(const Operator* call_op, Node* const* args,
size_t arg_count);
Node* ProcessCallArguments(const Operator* call_op, Node* callee,
interpreter::Register receiver, size_t arity);
Node* ProcessConstructArguments(const Operator* call_new_op, Node* callee,
......@@ -150,8 +155,16 @@ class BytecodeGraphBuilder {
void BuildLdaLookupContextSlot(TypeofMode typeof_mode);
void BuildLdaLookupGlobalSlot(TypeofMode typeof_mode);
void BuildStaLookupSlot(LanguageMode language_mode);
void BuildCall(TailCallMode tail_call_mode,
ConvertReceiverMode receiver_hint);
void BuildCallVarArgs(TailCallMode tail_call_mode,
ConvertReceiverMode receiver_hint);
void BuildCall(TailCallMode tail_call_mode, ConvertReceiverMode receiver_hint,
Node* const* args, size_t arg_count, int slot_id);
void BuildCall(TailCallMode tail_call_mode, ConvertReceiverMode receiver_hint,
std::initializer_list<Node*> args, int slot_id) {
BuildCall(tail_call_mode, receiver_hint, args.begin(), args.size(),
slot_id);
}
void BuildThrow();
void BuildBinaryOp(const Operator* op);
void BuildBinaryOpWithImmediate(const Operator* op);
void BuildCompareOp(const Operator* op);
......
......@@ -1005,9 +1005,26 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
if (tail_call_mode == TailCallMode::kDisallow) {
if (call_type == Call::NAMED_PROPERTY_CALL ||
call_type == Call::KEYED_PROPERTY_CALL) {
OutputCallProperty(callable, args, args.register_count(), feedback_slot);
if (args.register_count() == 1) {
OutputCallProperty0(callable, args[0], feedback_slot);
} else if (args.register_count() == 2) {
OutputCallProperty1(callable, args[0], args[1], feedback_slot);
} else if (args.register_count() == 3) {
OutputCallProperty2(callable, args[0], args[1], args[2], feedback_slot);
} else {
OutputCallProperty(callable, args, args.register_count(),
feedback_slot);
}
} else {
OutputCall(callable, args, args.register_count(), feedback_slot);
if (args.register_count() == 1) {
OutputCall0(callable, args[0], feedback_slot);
} else if (args.register_count() == 2) {
OutputCall1(callable, args[0], args[1], feedback_slot);
} else if (args.register_count() == 3) {
OutputCall2(callable, args[0], args[1], args[2], feedback_slot);
} else {
OutputCall(callable, args, args.register_count(), feedback_slot);
}
}
} else {
DCHECK(tail_call_mode == TailCallMode::kAllow);
......
......@@ -191,6 +191,21 @@ class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) {
SetOperand(3, operand3);
}
INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, uint32_t operand1,
uint32_t operand2, uint32_t operand3, uint32_t operand4,
BytecodeSourceInfo source_info = BytecodeSourceInfo()))
: bytecode_(bytecode),
operand_count_(5),
operand_scale_(OperandScale::kSingle),
source_info_(source_info) {
DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
SetOperand(0, operand0);
SetOperand(1, operand1);
SetOperand(2, operand2);
SetOperand(3, operand3);
SetOperand(4, operand4);
}
#define DEFINE_BYTECODE_NODE_CREATOR(Name, ...) \
template <typename... Operands> \
INLINE(static BytecodeNode Name(BytecodeSourceInfo source_info, \
......@@ -261,7 +276,7 @@ class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) {
OperandScale operand_scale,
BytecodeSourceInfo source_info, uint32_t operand0 = 0,
uint32_t operand1 = 0, uint32_t operand2 = 0,
uint32_t operand3 = 0))
uint32_t operand3 = 0, uint32_t operand4 = 0))
: bytecode_(bytecode),
operand_count_(operand_count),
operand_scale_(operand_scale),
......@@ -271,6 +286,7 @@ class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) {
operands_[1] = operand1;
operands_[2] = operand2;
operands_[3] = operand3;
operands_[4] = operand4;
}
template <Bytecode bytecode, AccumulatorUse accum_use>
......@@ -336,6 +352,29 @@ class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) {
operand2, operand3);
}
template <Bytecode bytecode, AccumulatorUse accum_use,
OperandType operand0_type, OperandType operand1_type,
OperandType operand2_type, OperandType operand3_type,
OperandType operand4_type>
INLINE(static BytecodeNode Create(BytecodeSourceInfo source_info,
uint32_t operand0, uint32_t operand1,
uint32_t operand2, uint32_t operand3,
uint32_t operand4)) {
DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type);
DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 3), operand3_type);
DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 4), operand4_type);
OperandScale scale = OperandScale::kSingle;
scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
scale = std::max(scale, ScaleForOperand<operand2_type>(operand2));
scale = std::max(scale, ScaleForOperand<operand3_type>(operand3));
scale = std::max(scale, ScaleForOperand<operand4_type>(operand4));
return BytecodeNode(bytecode, 5, scale, source_info, operand0, operand1,
operand2, operand3, operand4);
}
template <OperandType operand_type>
INLINE(static OperandScale ScaleForOperand(uint32_t operand)) {
if (BytecodeOperands::IsScalableUnsignedByte(operand_type)) {
......
......@@ -154,8 +154,21 @@ namespace interpreter {
/* Call operations */ \
V(Call, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kRegList, \
OperandType::kRegCount, OperandType::kIdx) \
V(Call0, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
OperandType::kIdx) \
V(Call1, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
OperandType::kReg, OperandType::kIdx) \
V(Call2, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
OperandType::kReg, OperandType::kReg, OperandType::kIdx) \
V(CallProperty, AccumulatorUse::kWrite, OperandType::kReg, \
OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \
V(CallProperty0, AccumulatorUse::kWrite, OperandType::kReg, \
OperandType::kReg, OperandType::kIdx) \
V(CallProperty1, AccumulatorUse::kWrite, OperandType::kReg, \
OperandType::kReg, OperandType::kReg, OperandType::kIdx) \
V(CallProperty2, AccumulatorUse::kWrite, OperandType::kReg, \
OperandType::kReg, OperandType::kReg, OperandType::kReg, \
OperandType::kIdx) \
V(CallWithSpread, AccumulatorUse::kWrite, OperandType::kReg, \
OperandType::kRegList, OperandType::kRegCount) \
V(TailCall, AccumulatorUse::kWrite, OperandType::kReg, \
......@@ -407,7 +420,7 @@ enum class Bytecode : uint8_t {
class V8_EXPORT_PRIVATE Bytecodes final {
public:
// The maximum number of operands a bytecode may have.
static const int kMaxOperands = 4;
static const int kMaxOperands = 5;
// Returns string representation of |bytecode|.
static const char* ToString(Bytecode bytecode);
......@@ -621,6 +634,12 @@ class V8_EXPORT_PRIVATE Bytecodes final {
// Returns true if the bytecode is a call or a constructor call.
static constexpr bool IsCallOrConstruct(Bytecode bytecode) {
return bytecode == Bytecode::kCall || bytecode == Bytecode::kCallProperty ||
bytecode == Bytecode::kCall0 ||
bytecode == Bytecode::kCallProperty0 ||
bytecode == Bytecode::kCall1 ||
bytecode == Bytecode::kCallProperty1 ||
bytecode == Bytecode::kCall2 ||
bytecode == Bytecode::kCallProperty2 ||
bytecode == Bytecode::kTailCall ||
bytecode == Bytecode::kConstruct ||
bytecode == Bytecode::kCallWithSpread ||
......
......@@ -451,13 +451,16 @@ Node* InterpreterAssembler::BytecodeOperandImmSmi(int operand_index) {
return SmiFromWord32(BytecodeOperandImm(operand_index));
}
Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
Node* InterpreterAssembler::BytecodeOperandIdxInt32(int operand_index) {
DCHECK(OperandType::kIdx ==
Bytecodes::GetOperandType(bytecode_, operand_index));
OperandSize operand_size =
Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
return ChangeUint32ToWord(
BytecodeUnsignedOperand(operand_index, operand_size));
return BytecodeUnsignedOperand(operand_index, operand_size);
}
Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
return ChangeUint32ToWord(BytecodeOperandIdxInt32(operand_index));
}
Node* InterpreterAssembler::BytecodeOperandIdxSmi(int operand_index) {
......
......@@ -32,6 +32,9 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
compiler::Node* BytecodeOperandFlag(int operand_index);
// Returns the 32-bit zero-extended index immediate for bytecode operand
// |operand_index| in the current bytecode.
compiler::Node* BytecodeOperandIdxInt32(int operand_index);
// Returns the word zero-extended index immediate for bytecode operand
// |operand_index| in the current bytecode.
compiler::Node* BytecodeOperandIdx(int operand_index);
// Returns the smi index immediate for bytecode operand |operand_index|
// in the current bytecode.
......
......@@ -4,6 +4,7 @@
#include "src/interpreter/interpreter.h"
#include <array>
#include <fstream>
#include <memory>
......@@ -129,11 +130,42 @@ void Interpreter::Initialize() {
DCHECK(IsDispatchTableInitialized());
}
bool Interpreter::ReuseExistingHandler(Bytecode bytecode,
OperandScale operand_scale) {
size_t index = GetDispatchTableIndex(bytecode, operand_scale);
switch (bytecode) {
case Bytecode::kCallProperty:
case Bytecode::kCallProperty0:
case Bytecode::kCallProperty1:
case Bytecode::kCallProperty2: {
const int offset = static_cast<int>(Bytecode::kCallProperty) -
static_cast<int>(Bytecode::kCall);
STATIC_ASSERT(offset ==
static_cast<int>(Bytecode::kCallProperty0) -
static_cast<int>(Bytecode::kCall0));
STATIC_ASSERT(offset ==
static_cast<int>(Bytecode::kCallProperty1) -
static_cast<int>(Bytecode::kCall1));
STATIC_ASSERT(offset ==
static_cast<int>(Bytecode::kCallProperty2) -
static_cast<int>(Bytecode::kCall2));
CHECK_LT(offset, index);
dispatch_table_[index] = dispatch_table_[index - offset];
return true;
break;
}
default:
return false;
}
}
void Interpreter::InstallBytecodeHandler(Zone* zone, Bytecode bytecode,
OperandScale operand_scale,
BytecodeGeneratorFunc generator) {
if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return;
if (ReuseExistingHandler(bytecode, operand_scale)) return;
size_t index = GetDispatchTableIndex(bytecode, operand_scale);
InterpreterDispatchDescriptor descriptor(isolate_);
compiler::CodeAssemblerState state(
isolate_, zone, descriptor, Code::ComputeFlags(Code::BYTECODE_HANDLER),
......@@ -144,7 +176,6 @@ void Interpreter::InstallBytecodeHandler(Zone* zone, Bytecode bytecode,
}
(this->*generator)(&assembler);
Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);
size_t index = GetDispatchTableIndex(bytecode, operand_scale);
dispatch_table_[index] = code->entry();
TraceCodegen(code);
PROFILE(isolate_, CodeCreateEvent(
......@@ -2161,6 +2192,35 @@ void Interpreter::DoJSCall(InterpreterAssembler* assembler,
__ Dispatch();
}
void Interpreter::DoJSCallN(InterpreterAssembler* assembler, int arg_count) {
const int kReceiverOperandIndex = 1;
const int kReceiverOperandCount = 1;
const int kSlotOperandIndex =
kReceiverOperandIndex + kReceiverOperandCount + arg_count;
const int kBoilerplatParameterCount = 7;
const int kReceiverParameterIndex = 5;
Node* function_reg = __ BytecodeOperandReg(0);
Node* function = __ LoadRegister(function_reg);
std::array<Node*, Bytecodes::kMaxOperands + kBoilerplatParameterCount> temp;
Callable call_ic = CodeFactory::CallIC(isolate_);
temp[0] = __ HeapConstant(call_ic.code());
temp[1] = function;
temp[2] = __ Int32Constant(arg_count);
temp[3] = __ BytecodeOperandIdxInt32(kSlotOperandIndex);
temp[4] = __ LoadFeedbackVector();
for (int i = 0; i < (arg_count + kReceiverOperandCount); ++i) {
Node* reg = __ BytecodeOperandReg(i + kReceiverOperandIndex);
temp[kReceiverParameterIndex + i] = __ LoadRegister(reg);
}
temp[kReceiverParameterIndex + arg_count + kReceiverOperandCount] =
__ GetContext();
Node* result = __ CallStubN(call_ic.descriptor(), 1,
arg_count + kBoilerplatParameterCount, &temp[0]);
__ SetAccumulator(result);
__ Dispatch();
}
// Call <callable> <receiver> <arg_count> <feedback_slot_id>
//
// Call a JSfunction or Callable in |callable| with the |receiver| and
......@@ -2170,15 +2230,36 @@ void Interpreter::DoCall(InterpreterAssembler* assembler) {
DoJSCall(assembler, TailCallMode::kDisallow);
}
// CallProperty <callable> <receiver> <arg_count> <feedback_slot_id>
//
// Call a JSfunction or Callable in |callable| with the |receiver| and
// |arg_count| arguments in subsequent registers. Collect type feedback into
// |feedback_slot_id|. The callable is known to be a property of the receiver.
void Interpreter::DoCall0(InterpreterAssembler* assembler) {
DoJSCallN(assembler, 0);
}
void Interpreter::DoCall1(InterpreterAssembler* assembler) {
DoJSCallN(assembler, 1);
}
void Interpreter::DoCall2(InterpreterAssembler* assembler) {
DoJSCallN(assembler, 2);
}
void Interpreter::DoCallProperty(InterpreterAssembler* assembler) {
// TODO(leszeks): Look into making the interpreter use the fact that the
// receiver is non-null.
DoJSCall(assembler, TailCallMode::kDisallow);
// Same as Call
UNREACHABLE();
}
void Interpreter::DoCallProperty0(InterpreterAssembler* assembler) {
// Same as Call0
UNREACHABLE();
}
void Interpreter::DoCallProperty1(InterpreterAssembler* assembler) {
// Same as Call1
UNREACHABLE();
}
void Interpreter::DoCallProperty2(InterpreterAssembler* assembler) {
// Same as Call2
UNREACHABLE();
}
// TailCall <callable> <receiver> <arg_count> <feedback_slot_id>
......@@ -2238,7 +2319,6 @@ void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) {
Node* context = __ GetContext();
Node* result_pair =
__ CallRuntimeN(function_id, context, first_arg, args_count, 2);
// Store the results in <first_return> and <first_return + 1>
Node* first_return_reg = __ BytecodeOperandReg(3);
Node* second_return_reg = __ NextRegister(first_return_reg);
......
......@@ -78,6 +78,10 @@ class Interpreter {
typedef void (Interpreter::*BytecodeGeneratorFunc)(InterpreterAssembler*);
// In the case of bytecodes that share handler implementations, copy the code
// into the bytecode's dispatcher table entry and return true.
bool ReuseExistingHandler(Bytecode bytecode, OperandScale operand_scale);
// Generates handler for given |bytecode| and |operand_scale| using
// |generator| and installs it into the dispatch table.
void InstallBytecodeHandler(Zone* zone, Bytecode bytecode,
......@@ -124,6 +128,10 @@ class Interpreter {
// Generates code to perform a JS call that collects type feedback.
void DoJSCall(InterpreterAssembler* assembler, TailCallMode tail_call_mode);
// Generates code to perform a JS call with a known number of arguments that
// collects type feedback.
void DoJSCallN(InterpreterAssembler* assembler, int n);
// Generates code to perform delete via function_id.
void DoDelete(Runtime::FunctionId function_id,
InterpreterAssembler* assembler);
......
......@@ -14,14 +14,14 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 15
bytecode array length: 14
bytecodes: [
/* 27 E> */ B(StackCheck),
/* 32 S> */ B(LdaUndefined),
B(Star), R(1),
B(LdaGlobal), U8(0), U8(4),
B(Star), R(0),
/* 39 E> */ B(Call), R(0), R(1), U8(1), U8(2),
/* 39 E> */ B(Call0), R(0), R(1), U8(2),
/* 44 S> */ B(Return),
]
constant pool: [
......
......@@ -11,7 +11,7 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 82
bytecode array length: 81
bytecodes: [
B(CreateFunctionContext), U8(3),
B(PushContext), R(0),
......@@ -41,12 +41,12 @@ bytecodes: [
B(Mov), R(closure), R(6),
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6),
B(Star), R(1),
/* 52 E> */ B(Call), R(1), R(2), U8(2), U8(3),
/* 52 E> */ B(Call1), R(1), R(2), R(3), U8(3),
/* 62 S> */ B(LdaUndefined),
B(Star), R(2),
/* 69 E> */ B(LdaLookupGlobalSlot), U8(1), U8(9), U8(1),
B(Star), R(1),
/* 69 E> */ B(Call), R(1), R(2), U8(1), U8(7),
/* 69 E> */ B(Call0), R(1), R(2), U8(7),
/* 74 S> */ B(Return),
]
constant pool: [
......
......@@ -22,7 +22,7 @@ snippet: "
"
frame size: 6
parameter count: 1
bytecode array length: 37
bytecode array length: 36
bytecodes: [
B(Mov), R(closure), R(0),
/* 99 E> */ B(StackCheck),
......@@ -34,7 +34,7 @@ bytecodes: [
B(Mov), R(this), R(3),
B(CallRuntime), U16(Runtime::kLoadFromSuper), R(3), U8(3),
B(Star), R(1),
/* 117 E> */ B(Call), R(1), R(this), U8(1), U8(2),
/* 117 E> */ B(Call0), R(1), R(this), U8(2),
B(Star), R(1),
/* 126 E> */ B(AddSmi), I8(1), R(1), U8(8),
/* 131 S> */ B(Return),
......
......@@ -77,7 +77,7 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 22
bytecode array length: 21
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
......@@ -86,7 +86,7 @@ bytecodes: [
B(Star), R(2),
B(CreateClosure), U8(0), U8(4), U8(2),
B(Star), R(1),
/* 64 E> */ B(Call), R(1), R(2), U8(1), U8(2),
/* 64 E> */ B(Call0), R(1), R(2), U8(2),
/* 68 S> */ B(LdaCurrentContextSlot), U8(4),
/* 78 S> */ B(Return),
]
......@@ -390,7 +390,7 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 792
bytecode array length: 791
bytecodes: [
B(CreateFunctionContext), U8(254),
B(PushContext), R(0),
......@@ -905,7 +905,7 @@ bytecodes: [
B(Star), R(2),
B(LdaGlobal), U8(0), U8(4),
B(Star), R(1),
/* 3438 E> */ B(Call), R(1), R(2), U8(1), U8(2),
/* 3438 E> */ B(Call0), R(1), R(2), U8(2),
/* 3454 S> */ B(LdaSmi), I8(100),
/* 3454 E> */ B(Wide), B(StaCurrentContextSlot), U16(256),
/* 3459 S> */ B(Wide), B(LdaCurrentContextSlot), U16(256),
......
......@@ -104,7 +104,7 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 32
bytecode array length: 31
bytecodes: [
B(LdaConstant), U8(0),
B(Star), R(1),
......@@ -117,7 +117,7 @@ bytecodes: [
B(Star), R(2),
B(LdaGlobal), U8(1), U8(2),
B(Star), R(1),
/* 16 E> */ B(Call), R(1), R(2), U8(1), U8(5),
/* 16 E> */ B(Call0), R(1), R(2), U8(5),
B(Star), R(0),
/* 20 S> */ B(Return),
]
......
......@@ -39,7 +39,7 @@ bytecodes: [
B(Mov), R(closure), R(6),
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6),
B(Star), R(1),
/* 41 E> */ B(Call), R(1), R(2), U8(2), U8(2),
/* 41 E> */ B(Call1), R(1), R(2), R(3), U8(2),
/* 53 S> */ B(Return),
]
constant pool: [
......
......@@ -11,7 +11,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 272
bytecode array length: 270
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
......@@ -22,13 +22,13 @@ bytecodes: [
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(1), U8(3),
B(Star), R(14),
B(CallProperty), R(14), R(13), U8(1), U8(5),
B(CallProperty0), R(14), R(13), U8(5),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(2),
/* 45 S> */ B(LdaNamedProperty), R(2), U8(2), U8(9),
B(Star), R(13),
/* 45 E> */ B(CallProperty), R(13), R(2), U8(1), U8(7),
/* 45 E> */ B(CallProperty0), R(13), R(2), U8(7),
B(Star), R(3),
/* 45 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(3), U8(1),
B(ToBooleanLogicalNot),
......@@ -45,7 +45,7 @@ bytecodes: [
B(Mov), R(0), R(1),
B(LdaZero),
B(Star), R(4),
B(JumpLoop), U8(51), I8(0),
B(JumpLoop), U8(50), I8(0),
B(Jump), U8(36),
B(Star), R(13),
B(Ldar), R(closure),
......@@ -142,9 +142,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[7, 126, 132],
[10, 90, 92],
[199, 209, 211],
[7, 124, 130],
[10, 88, 90],
[197, 207, 209],
]
---
......@@ -154,7 +154,7 @@ snippet: "
"
frame size: 16
parameter count: 1
bytecode array length: 286
bytecode array length: 284
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
......@@ -165,14 +165,14 @@ bytecodes: [
B(Mov), R(context), R(13),
/* 68 S> */ B(LdaNamedProperty), R(0), U8(1), U8(2),
B(Star), R(15),
B(CallProperty), R(15), R(0), U8(1), U8(4),
B(CallProperty0), R(15), R(0), U8(4),
B(Mov), R(0), R(14),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(3),
/* 65 S> */ B(LdaNamedProperty), R(3), U8(2), U8(8),
B(Star), R(14),
/* 65 E> */ B(CallProperty), R(14), R(3), U8(1), U8(6),
/* 65 E> */ B(CallProperty0), R(14), R(3), U8(6),
B(Star), R(4),
/* 65 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(4), U8(1),
B(ToBooleanLogicalNot),
......@@ -292,9 +292,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[11, 129, 135],
[14, 93, 95],
[203, 213, 215],
[11, 127, 133],
[14, 91, 93],
[201, 211, 213],
]
---
......@@ -306,7 +306,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 290
bytecode array length: 288
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
......@@ -317,13 +317,13 @@ bytecodes: [
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(1), U8(3),
B(Star), R(14),
B(CallProperty), R(14), R(13), U8(1), U8(5),
B(CallProperty0), R(14), R(13), U8(5),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(2),
/* 45 S> */ B(LdaNamedProperty), R(2), U8(2), U8(9),
B(Star), R(13),
/* 45 E> */ B(CallProperty), R(13), R(2), U8(1), U8(7),
/* 45 E> */ B(CallProperty0), R(13), R(2), U8(7),
B(Star), R(3),
/* 45 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(3), U8(1),
B(ToBooleanLogicalNot),
......@@ -348,7 +348,7 @@ bytecodes: [
/* 104 S> */ B(Jump), U8(8),
B(LdaZero),
B(Star), R(4),
B(JumpLoop), U8(69), I8(0),
B(JumpLoop), U8(68), I8(0),
B(Jump), U8(36),
B(Star), R(13),
B(Ldar), R(closure),
......@@ -445,9 +445,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[7, 144, 150],
[10, 108, 110],
[217, 227, 229],
[7, 142, 148],
[10, 106, 108],
[215, 225, 227],
]
---
......@@ -457,7 +457,7 @@ snippet: "
"
frame size: 14
parameter count: 1
bytecode array length: 297
bytecode array length: 295
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(2), U8(1), R(8),
......@@ -470,13 +470,13 @@ bytecodes: [
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(2), U8(4),
B(Star), R(13),
B(CallProperty), R(13), R(12), U8(1), U8(6),
B(CallProperty0), R(13), R(12), U8(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(1),
/* 74 S> */ B(LdaNamedProperty), R(1), U8(3), U8(10),
B(Star), R(12),
/* 74 E> */ B(CallProperty), R(12), R(1), U8(1), U8(8),
/* 74 E> */ B(CallProperty0), R(12), R(1), U8(8),
B(Star), R(2),
/* 74 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(2), U8(1),
B(ToBooleanLogicalNot),
......@@ -600,8 +600,8 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
[15, 140, 146],
[18, 104, 106],
[214, 224, 226],
[15, 138, 144],
[18, 102, 104],
[212, 222, 224],
]
......@@ -29,14 +29,14 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 16
bytecode array length: 15
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdaUndefined),
B(Star), R(1),
B(CreateClosure), U8(0), U8(4), U8(2),
B(Star), R(0),
/* 56 E> */ B(Call), R(0), R(1), U8(1), U8(2),
/* 56 E> */ B(Call0), R(0), R(1), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
......@@ -60,7 +60,7 @@ bytecodes: [
B(Star), R(0),
B(LdaSmi), I8(1),
B(Star), R(2),
/* 67 E> */ B(Call), R(0), R(1), U8(2), U8(2),
/* 67 E> */ B(Call1), R(0), R(1), R(2), U8(2),
/* 71 S> */ B(Return),
]
constant pool: [
......
......@@ -280,7 +280,7 @@ snippet: "
"
frame size: 18
parameter count: 1
bytecode array length: 775
bytecode array length: 773
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(35),
......@@ -293,7 +293,7 @@ bytecodes: [
B(JumpIfTrue), U8(60),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrue), U8(154),
B(JumpIfTrue), U8(153),
B(LdaSmi), I8(78),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
......@@ -353,7 +353,7 @@ bytecodes: [
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(2), U8(3),
B(Star), R(13),
B(CallProperty), R(13), R(12), U8(1), U8(5),
B(CallProperty0), R(13), R(12), U8(5),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
/* 30 E> */ B(StaContextSlot), R(1), U8(7), U8(0),
......@@ -362,7 +362,7 @@ bytecodes: [
B(JumpIfTrue), U8(18),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrue), U8(134),
B(JumpIfTrue), U8(133),
B(LdaSmi), I8(78),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kAbort), R(12), U8(1),
......@@ -370,7 +370,7 @@ bytecodes: [
B(Star), R(13),
B(LdaNamedProperty), R(13), U8(3), U8(9),
B(Star), R(12),
/* 27 E> */ B(CallProperty), R(12), R(13), U8(1), U8(7),
/* 27 E> */ B(CallProperty0), R(12), R(13), U8(7),
/* 27 E> */ B(StaContextSlot), R(1), U8(8), U8(0),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(12), U8(1),
......@@ -443,7 +443,7 @@ bytecodes: [
B(PopContext), R(2),
B(LdaZero),
B(StaContextSlot), R(1), U8(9), U8(0),
B(JumpLoop), U8(218), I8(0),
B(JumpLoop), U8(217), I8(0),
B(Jump), U8(44),
B(Star), R(12),
B(Ldar), R(closure),
......@@ -621,12 +621,12 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["function"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
FIXED_ARRAY_TYPE,
Smi [579],
Smi [577],
]
handlers: [
[53, 694, 700],
[149, 445, 451],
[152, 401, 403],
[547, 563, 565],
[53, 692, 698],
[149, 443, 449],
[152, 399, 401],
[545, 561, 563],
]
......@@ -40,7 +40,7 @@ bytecodes: [
B(Mov), R(closure), R(6),
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6),
B(Star), R(1),
/* 14 E> */ B(Call), R(1), R(2), U8(2), U8(2),
/* 14 E> */ B(Call1), R(1), R(2), R(3), U8(2),
/* 35 S> */ B(LdaLookupGlobalSlot), U8(2), U8(6), U8(1),
/* 45 S> */ B(Return),
]
......@@ -86,7 +86,7 @@ bytecodes: [
B(Mov), R(closure), R(6),
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6),
B(Star), R(1),
/* 14 E> */ B(Call), R(1), R(2), U8(2), U8(2),
/* 14 E> */ B(Call1), R(1), R(2), R(3), U8(2),
/* 35 S> */ B(LdaLookupGlobalSlotInsideTypeof), U8(2), U8(6), U8(1),
B(TypeOf),
/* 52 S> */ B(Return),
......@@ -135,7 +135,7 @@ bytecodes: [
B(Mov), R(closure), R(6),
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6),
B(Star), R(1),
/* 29 E> */ B(Call), R(1), R(2), U8(2), U8(2),
/* 29 E> */ B(Call1), R(1), R(2), R(3), U8(2),
/* 39 S> */ B(Return),
]
constant pool: [
......@@ -185,7 +185,7 @@ bytecodes: [
B(Mov), R(closure), R(6),
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6),
B(Star), R(1),
/* 44 E> */ B(Call), R(1), R(2), U8(2), U8(2),
/* 44 E> */ B(Call1), R(1), R(2), R(3), U8(2),
/* 66 S> */ B(LdaLookupContextSlot), U8(2), U8(6), U8(1),
/* 76 S> */ B(Return),
]
......@@ -236,7 +236,7 @@ bytecodes: [
B(Mov), R(closure), R(6),
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6),
B(Star), R(1),
/* 40 E> */ B(Call), R(1), R(2), U8(2), U8(2),
/* 40 E> */ B(Call1), R(1), R(2), R(3), U8(2),
/* 62 S> */ B(LdaLookupGlobalSlot), U8(2), U8(6), U8(1),
/* 72 S> */ B(Return),
]
......
......@@ -226,7 +226,7 @@ bytecodes: [
B(Star), R(4),
B(LdaSmi), I8(42),
B(Star), R(6),
/* 32 E> */ B(Call), R(4), R(5), U8(2), U8(2),
/* 32 E> */ B(Call1), R(4), R(5), R(6), U8(2),
B(Ldar), R(closure),
B(CreateBlockContext), U8(2),
B(PushContext), R(1),
......@@ -244,7 +244,7 @@ bytecodes: [
B(Star), R(4),
B(LdaSmi), I8(42),
B(Star), R(6),
/* 52 E> */ B(Call), R(4), R(5), U8(2), U8(4),
/* 52 E> */ B(Call1), R(4), R(5), R(6), U8(4),
B(PopContext), R(1),
B(LdaUndefined),
/* 64 S> */ B(Return),
......@@ -853,7 +853,7 @@ snippet: "
"
frame size: 9
parameter count: 2
bytecode array length: 170
bytecode array length: 171
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(28),
......@@ -924,7 +924,7 @@ bytecodes: [
B(Star), R(6),
/* 41 E> */ B(LdaNamedProperty), R(6), U8(2), U8(6),
B(Star), R(6),
/* 31 E> */ B(CallProperty), R(3), R(4), U8(3), U8(2),
/* 31 E> */ B(CallProperty2), R(3), R(4), R(5), R(6), U8(2),
B(LdaUndefined),
/* 45 S> */ B(Return),
]
......
......@@ -13,13 +13,13 @@ snippet: "
"
frame size: 1
parameter count: 2
bytecode array length: 14
bytecode array length: 13
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 16 S> */ B(Nop),
/* 24 E> */ B(LdaNamedProperty), R(arg0), U8(0), U8(4),
B(Star), R(0),
/* 25 E> */ B(CallProperty), R(0), R(arg0), U8(1), U8(2),
/* 25 E> */ B(CallProperty0), R(0), R(arg0), U8(2),
/* 33 S> */ B(Return),
]
constant pool: [
......@@ -33,18 +33,15 @@ snippet: "
function f(a, b, c) { return a.func(b, c); }
f(new (function Obj() { this.func = function() { return; }})(), 1, 2)
"
frame size: 4
frame size: 1
parameter count: 4
bytecode array length: 23
bytecode array length: 15
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 22 S> */ B(Nop),
/* 30 E> */ B(LdaNamedProperty), R(arg0), U8(0), U8(4),
B(Star), R(0),
B(Mov), R(arg0), R(1),
B(Mov), R(arg1), R(2),
B(Mov), R(arg2), R(3),
/* 31 E> */ B(CallProperty), R(0), R(1), U8(3), U8(2),
/* 31 E> */ B(CallProperty2), R(0), R(arg0), R(arg1), R(arg2), U8(2),
/* 43 S> */ B(Return),
]
constant pool: [
......@@ -58,9 +55,9 @@ snippet: "
function f(a, b) { return a.func(b + b, b); }
f(new (function Obj() { this.func = function() { return; }})(), 1)
"
frame size: 4
frame size: 3
parameter count: 3
bytecode array length: 27
bytecode array length: 22
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 19 S> */ B(Nop),
......@@ -69,9 +66,7 @@ bytecodes: [
B(Ldar), R(arg1),
/* 35 E> */ B(Add), R(arg1), U8(6),
B(Star), R(2),
B(Mov), R(arg0), R(1),
B(Mov), R(arg1), R(3),
/* 28 E> */ B(CallProperty), R(0), R(1), U8(3), U8(2),
/* 28 E> */ B(CallProperty2), R(0), R(arg0), R(2), R(arg1), U8(2),
/* 44 S> */ B(Return),
]
constant pool: [
......@@ -216,7 +211,7 @@ snippet: "
"
frame size: 1
parameter count: 2
bytecode array length: 667
bytecode array length: 665
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 17 S> */ B(Nop),
......@@ -478,7 +473,7 @@ bytecodes: [
/* 1169 S> */ B(Nop),
/* 1177 E> */ B(Wide), B(LdaNamedProperty), R16(arg0), U16(0), U16(260),
B(Star), R(0),
/* 1178 E> */ B(Wide), B(CallProperty), R16(0), R16(arg0), U16(1), U16(258),
/* 1178 E> */ B(Wide), B(CallProperty0), R16(0), R16(arg0), U16(258),
/* 1186 S> */ B(Return),
]
constant pool: [
......@@ -494,7 +489,7 @@ snippet: "
"
frame size: 5
parameter count: 2
bytecode array length: 55
bytecode array length: 52
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 16 S> */ B(Nop),
......@@ -502,20 +497,19 @@ bytecodes: [
B(Star), R(2),
B(LdaSmi), I8(1),
B(Star), R(4),
B(Mov), R(arg0), R(3),
/* 25 E> */ B(CallProperty), R(2), R(3), U8(2), U8(6),
/* 25 E> */ B(CallProperty1), R(2), R(arg0), R(4), U8(6),
B(Star), R(2),
/* 32 E> */ B(LdaNamedProperty), R(2), U8(0), U8(10),
B(Star), R(1),
B(LdaSmi), I8(2),
B(Star), R(3),
/* 33 E> */ B(CallProperty), R(1), R(2), U8(2), U8(4),
/* 33 E> */ B(CallProperty1), R(1), R(2), R(3), U8(4),
B(Star), R(1),
/* 40 E> */ B(LdaNamedProperty), R(1), U8(0), U8(12),
B(Star), R(0),
B(LdaSmi), I8(3),
B(Star), R(2),
/* 41 E> */ B(CallProperty), R(0), R(1), U8(2), U8(2),
/* 41 E> */ B(CallProperty1), R(0), R(1), R(2), U8(2),
/* 50 S> */ B(Return),
]
constant pool: [
......
......@@ -56,7 +56,7 @@ bytecodes: [
B(Star), R(0),
B(LdaConstant), U8(2),
B(Star), R(2),
/* 48 E> */ B(CallProperty), R(0), R(1), U8(2), U8(2),
/* 48 E> */ B(CallProperty1), R(0), R(1), R(2), U8(2),
/* 62 S> */ B(Return),
]
constant pool: [
......
......@@ -38,7 +38,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
Register other(reg.index() + 1);
Register wide(128);
RegisterList reg_list;
RegisterList pair(0, 2), triple(0, 3);
RegisterList single(0, 1), pair(0, 2), triple(0, 3);
// Emit argument creation operations.
builder.CreateArguments(CreateArgumentsType::kMappedArguments)
......@@ -144,8 +144,14 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
// Call operations.
builder.Call(reg, reg_list, 1, Call::GLOBAL_CALL)
.Call(reg, single, 1, Call::GLOBAL_CALL)
.Call(reg, pair, 1, Call::GLOBAL_CALL)
.Call(reg, triple, 1, Call::GLOBAL_CALL)
.Call(reg, reg_list, 1, Call::NAMED_PROPERTY_CALL,
TailCallMode::kDisallow)
.Call(reg, single, 1, Call::NAMED_PROPERTY_CALL)
.Call(reg, pair, 1, Call::NAMED_PROPERTY_CALL)
.Call(reg, triple, 1, Call::NAMED_PROPERTY_CALL)
.Call(reg, reg_list, 1, Call::GLOBAL_CALL, TailCallMode::kAllow)
.CallRuntime(Runtime::kIsArray, reg)
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg_list, pair)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment