[vm/compiler] Unify VariadicDefinition and VariadicDefinitionWithEmbeddedInputs

The unified base class for instructions with variable number of inputs
now keeps inputs in GrowableArray<Value*> (no indirection, no extra zone
memory allocation).

InputsArray is changed to GrowableArray<Value*> instead of
ZoneGrowableArray and passed as rvalue reference.

TEST=ci (pure refactoring)

Change-Id: I4a6f6835516c118c2b924720bcd8a964858e4368
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253820
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Alexander Markov 2022-08-08 15:58:40 +00:00 committed by Commit Bot
parent 56f8caa9d4
commit 964c756faa
12 changed files with 206 additions and 195 deletions

View file

@ -4,6 +4,8 @@
#include "vm/compiler/aot/aot_call_specializer.h"
#include <utility>
#include "vm/bit_vector.h"
#include "vm/compiler/aot/precompiler.h"
#include "vm/compiler/backend/branch_optimizer.h"
@ -199,14 +201,15 @@ bool AotCallSpecializer::TryReplaceWithHaveSameRuntimeType(
cls.LookupStaticFunctionAllowPrivate(Symbols::HaveSameRuntimeType()));
ASSERT(!have_same_runtime_type.IsNull());
InputsArray* args = new (Z) InputsArray(Z, 2);
args->Add(left->ArgumentValueAt(0)->CopyWithType(Z));
args->Add(right->ArgumentValueAt(0)->CopyWithType(Z));
InputsArray args(Z, 2);
args.Add(left->ArgumentValueAt(0)->CopyWithType(Z));
args.Add(right->ArgumentValueAt(0)->CopyWithType(Z));
const intptr_t kTypeArgsLen = 0;
StaticCallInstr* static_call = new (Z) StaticCallInstr(
call->source(), have_same_runtime_type, kTypeArgsLen,
Object::null_array(), // argument_names
args, call->deopt_id(), call->CallCount(), ICData::kOptimized);
StaticCallInstr* static_call = new (Z)
StaticCallInstr(call->source(), have_same_runtime_type, kTypeArgsLen,
Object::null_array(), // argument_names
std::move(args), call->deopt_id(), call->CallCount(),
ICData::kOptimized);
static_call->SetResultType(Z, CompileType::FromCid(kBoolCid));
ReplaceCall(call, static_call);
// ReplaceCall moved environment from 'call' to 'static_call'.
@ -992,30 +995,30 @@ bool AotCallSpecializer::TryExpandCallThroughGetter(const Class& receiver_class,
const intptr_t receiver_idx = call->type_args_len() > 0 ? 1 : 0;
InputsArray* get_arguments = new (Z) InputsArray(Z, 1);
get_arguments->Add(call->ArgumentValueAt(receiver_idx)->CopyWithType(Z));
InstanceCallInstr* invoke_get = new (Z)
InstanceCallInstr(call->source(), getter_name, Token::kGET, get_arguments,
/*type_args_len=*/0,
/*argument_names=*/Object::empty_array(),
/*checked_argument_count=*/1,
thread()->compiler_state().GetNextDeoptId());
InputsArray get_arguments(Z, 1);
get_arguments.Add(call->ArgumentValueAt(receiver_idx)->CopyWithType(Z));
InstanceCallInstr* invoke_get = new (Z) InstanceCallInstr(
call->source(), getter_name, Token::kGET, std::move(get_arguments),
/*type_args_len=*/0,
/*argument_names=*/Object::empty_array(),
/*checked_argument_count=*/1,
thread()->compiler_state().GetNextDeoptId());
// Arguments to the .call() are the same as arguments to the
// original call (including type arguments), but receiver
// is replaced with the result of the get.
InputsArray* call_arguments = new (Z) InputsArray(Z, call->ArgumentCount());
InputsArray call_arguments(Z, call->ArgumentCount());
if (call->type_args_len() > 0) {
call_arguments->Add(call->ArgumentValueAt(0)->CopyWithType(Z));
call_arguments.Add(call->ArgumentValueAt(0)->CopyWithType(Z));
}
call_arguments->Add(new (Z) Value(invoke_get));
call_arguments.Add(new (Z) Value(invoke_get));
for (intptr_t i = receiver_idx + 1; i < call->ArgumentCount(); i++) {
call_arguments->Add(call->ArgumentValueAt(i)->CopyWithType(Z));
call_arguments.Add(call->ArgumentValueAt(i)->CopyWithType(Z));
}
InstanceCallInstr* invoke_call = new (Z) InstanceCallInstr(
call->source(), Symbols::Call(), Token::kILLEGAL, call_arguments,
call->type_args_len(), call->argument_names(),
call->source(), Symbols::Call(), Token::kILLEGAL,
std::move(call_arguments), call->type_args_len(), call->argument_names(),
/*checked_argument_count=*/1,
thread()->compiler_state().GetNextDeoptId());
@ -1110,10 +1113,10 @@ bool AotCallSpecializer::TryReplaceInstanceOfWithRangeCheck(
ConstantInstr* upper_cid =
flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(upper_limit)));
InputsArray* args = new (Z) InputsArray(Z, 3);
args->Add(new (Z) Value(left_cid));
args->Add(new (Z) Value(lower_cid));
args->Add(new (Z) Value(upper_cid));
InputsArray args(Z, 3);
args.Add(new (Z) Value(left_cid));
args.Add(new (Z) Value(lower_cid));
args.Add(new (Z) Value(upper_cid));
const Library& dart_internal = Library::Handle(Z, Library::InternalLibrary());
const String& target_name = Symbols::_classRangeCheck();
@ -1127,10 +1130,10 @@ bool AotCallSpecializer::TryReplaceInstanceOfWithRangeCheck(
StaticCallInstr* new_call = new (Z) StaticCallInstr(
call->source(), target, kTypeArgsLen,
Object::null_array(), // argument_names
args, call->deopt_id(), call->CallCount(), ICData::kOptimized);
std::move(args), call->deopt_id(), call->CallCount(), ICData::kOptimized);
Environment* copy =
call->env()->DeepCopy(Z, call->env()->Length() - call->ArgumentCount());
for (intptr_t i = 0; i < args->length(); ++i) {
for (intptr_t i = 0; i < new_call->InputCount(); ++i) {
copy->PushValue(new (Z) Value(new_call->ArgumentAt(i)));
}
call->RemoveEnvironment();

View file

@ -4911,14 +4911,14 @@ DispatchTableCallInstr* DispatchTableCallInstr::FromCall(
Value* cid,
const Function& interface_target,
const compiler::TableSelector* selector) {
InputsArray* args = new (zone) InputsArray(zone, call->ArgumentCount() + 1);
InputsArray args(zone, call->ArgumentCount() + 1);
for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
args->Add(call->ArgumentValueAt(i)->CopyWithType());
args.Add(call->ArgumentValueAt(i)->CopyWithType());
}
args->Add(cid);
auto dispatch_table_call = new (zone)
DispatchTableCallInstr(call->source(), interface_target, selector, args,
call->type_args_len(), call->argument_names());
args.Add(cid);
auto dispatch_table_call = new (zone) DispatchTableCallInstr(
call->source(), interface_target, selector, std::move(args),
call->type_args_len(), call->argument_names());
return dispatch_table_call;
}
@ -6351,14 +6351,14 @@ bool Utf8ScanInstr::IsScanFlagsUnboxed() const {
}
InvokeMathCFunctionInstr::InvokeMathCFunctionInstr(
ZoneGrowableArray<Value*>* inputs,
InputsArray&& inputs,
intptr_t deopt_id,
MethodRecognizer::Kind recognized_kind,
const InstructionSource& source)
: VariadicDefinition(inputs, source, deopt_id),
: VariadicDefinition(std::move(inputs), source, deopt_id),
recognized_kind_(recognized_kind),
token_pos_(source.token_pos) {
ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_));
ASSERT(InputCount() == ArgumentCountFor(recognized_kind_));
}
intptr_t InvokeMathCFunctionInstr::ArgumentCountFor(
@ -6997,13 +6997,13 @@ LocationSummary* CCallInstr::MakeLocationSummaryInternal(
CCallInstr::CCallInstr(
const compiler::ffi::NativeCallingConvention& native_calling_convention,
InputsArray* inputs)
: VariadicDefinition(inputs, DeoptId::kNone),
InputsArray&& inputs)
: VariadicDefinition(std::move(inputs), DeoptId::kNone),
native_calling_convention_(native_calling_convention) {
#ifdef DEBUG
const intptr_t num_inputs =
native_calling_convention.argument_locations().length() + 1;
ASSERT(num_inputs == inputs->length());
ASSERT(num_inputs == InputCount());
#endif
}

View file

@ -780,7 +780,7 @@ class BinaryFeedback : public ZoneAllocated {
friend class Cids;
};
typedef ZoneGrowableArray<Value*> InputsArray;
typedef GrowableArray<Value*> InputsArray;
typedef ZoneGrowableArray<PushArgumentInstr*> PushArgumentsArray;
template <typename Trait>
@ -2534,43 +2534,29 @@ class TemplateDefinition : public CSETrait<Definition, PureDefinition>::Base {
class VariadicDefinition : public Definition {
public:
explicit VariadicDefinition(InputsArray* inputs,
explicit VariadicDefinition(InputsArray&& inputs,
intptr_t deopt_id = DeoptId::kNone)
: Definition(deopt_id), inputs_(inputs) {
for (intptr_t i = 0, n = inputs_->length(); i < n; ++i) {
SetInputAt(i, (*inputs_)[i]);
: Definition(deopt_id), inputs_(std::move(inputs)) {
for (intptr_t i = 0, n = inputs_.length(); i < n; ++i) {
SetInputAt(i, inputs_[i]);
}
}
VariadicDefinition(InputsArray* inputs,
VariadicDefinition(InputsArray&& inputs,
const InstructionSource& source,
intptr_t deopt_id = DeoptId::kNone)
: Definition(source, deopt_id), inputs_(inputs) {
for (intptr_t i = 0, n = inputs_->length(); i < n; ++i) {
SetInputAt(i, (*inputs_)[i]);
: Definition(source, deopt_id), inputs_(std::move(inputs)) {
for (intptr_t i = 0, n = inputs_.length(); i < n; ++i) {
SetInputAt(i, inputs_[i]);
}
}
intptr_t InputCount() const { return inputs_->length(); }
Value* InputAt(intptr_t i) const { return (*inputs_)[i]; }
protected:
InputsArray* inputs_;
private:
void RawSetInputAt(intptr_t i, Value* value) { (*inputs_)[i] = value; }
};
class VariadicDefinitionWithEmbeddedInputs : public Definition {
public:
explicit VariadicDefinitionWithEmbeddedInputs(
const intptr_t num_inputs,
intptr_t deopt_id = DeoptId::kNone)
explicit VariadicDefinition(const intptr_t num_inputs,
intptr_t deopt_id = DeoptId::kNone)
: Definition(deopt_id), inputs_(num_inputs) {
inputs_.EnsureLength(num_inputs, nullptr);
}
VariadicDefinitionWithEmbeddedInputs(const intptr_t num_inputs,
const InstructionSource& source,
intptr_t deopt_id = DeoptId::kNone)
VariadicDefinition(const intptr_t num_inputs,
const InstructionSource& source,
intptr_t deopt_id = DeoptId::kNone)
: Definition(source, deopt_id), inputs_(num_inputs) {
inputs_.EnsureLength(num_inputs, nullptr);
}
@ -2579,16 +2565,16 @@ class VariadicDefinitionWithEmbeddedInputs : public Definition {
Value* InputAt(intptr_t i) const { return inputs_[i]; }
protected:
GrowableArray<Value*> inputs_;
InputsArray inputs_;
private:
void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
};
class PhiInstr : public VariadicDefinitionWithEmbeddedInputs {
class PhiInstr : public VariadicDefinition {
public:
PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
: VariadicDefinitionWithEmbeddedInputs(num_inputs),
: VariadicDefinition(num_inputs),
block_(block),
representation_(kTagged),
is_alive_(false),
@ -4019,14 +4005,14 @@ class TemplateDartCall : public VariadicDefinition {
TemplateDartCall(intptr_t deopt_id,
intptr_t type_args_len,
const Array& argument_names,
InputsArray* inputs,
InputsArray&& inputs,
const InstructionSource& source)
: VariadicDefinition(inputs, source, deopt_id),
: VariadicDefinition(std::move(inputs), source, deopt_id),
type_args_len_(type_args_len),
argument_names_(argument_names),
token_pos_(source.token_pos) {
ASSERT(argument_names.IsZoneHandle() || argument_names.InVMIsolateHeap());
ASSERT(inputs_->length() >= kExtraInputs);
ASSERT(InputCount() >= kExtraInputs);
}
inline StringPtr Selector();
@ -4054,7 +4040,7 @@ class TemplateDartCall : public VariadicDefinition {
// Caution: Must override Instruction::ArgumentCount().
intptr_t ArgumentCount() const {
return push_arguments_ != nullptr ? push_arguments_->length()
: inputs_->length() - kExtraInputs;
: InputCount() - kExtraInputs;
}
virtual intptr_t ArgumentsSize() const { return ArgumentCount(); }
@ -4070,15 +4056,15 @@ class TemplateDartCall : public VariadicDefinition {
ASSERT(push_arguments_ == nullptr);
ASSERT(push_arguments->length() == ArgumentCount());
SetPushArguments(push_arguments);
ASSERT(inputs_->length() == ArgumentCount() + kExtraInputs);
const intptr_t extra_inputs_base = inputs_->length() - kExtraInputs;
ASSERT(InputCount() == ArgumentCount() + kExtraInputs);
const intptr_t extra_inputs_base = InputCount() - kExtraInputs;
for (intptr_t i = 0, n = ArgumentCount(); i < n; ++i) {
InputAt(i)->RemoveFromUseList();
}
for (intptr_t i = 0; i < kExtraInputs; ++i) {
SetInputAt(i, InputAt(extra_inputs_base + i));
}
inputs_->TruncateTo(kExtraInputs);
inputs_.TruncateTo(kExtraInputs);
}
intptr_t type_args_len() const { return type_args_len_; }
const Array& argument_names() const { return argument_names_; }
@ -4100,7 +4086,7 @@ class TemplateDartCall : public VariadicDefinition {
class ClosureCallInstr : public TemplateDartCall<1> {
public:
ClosureCallInstr(InputsArray* inputs,
ClosureCallInstr(InputsArray&& inputs,
intptr_t type_args_len,
const Array& argument_names,
const InstructionSource& source,
@ -4108,7 +4094,7 @@ class ClosureCallInstr : public TemplateDartCall<1> {
: TemplateDartCall(deopt_id,
type_args_len,
argument_names,
inputs,
std::move(inputs),
source) {}
DECLARE_INSTRUCTION(ClosureCall)
@ -4131,7 +4117,7 @@ class InstanceCallBaseInstr : public TemplateDartCall<0> {
InstanceCallBaseInstr(const InstructionSource& source,
const String& function_name,
Token::Kind token_kind,
InputsArray* arguments,
InputsArray&& arguments,
intptr_t type_args_len,
const Array& argument_names,
const ICData* ic_data,
@ -4141,7 +4127,7 @@ class InstanceCallBaseInstr : public TemplateDartCall<0> {
: TemplateDartCall(deopt_id,
type_args_len,
argument_names,
arguments,
std::move(arguments),
source),
ic_data_(ic_data),
function_name_(function_name),
@ -4153,7 +4139,7 @@ class InstanceCallBaseInstr : public TemplateDartCall<0> {
ASSERT(function_name.IsNotTemporaryScopedHandle());
ASSERT(interface_target.IsNotTemporaryScopedHandle());
ASSERT(tearoff_interface_target.IsNotTemporaryScopedHandle());
ASSERT(!arguments->is_empty());
ASSERT(InputCount() > 0);
ASSERT(Token::IsBinaryOperator(token_kind) ||
Token::IsEqualityOperator(token_kind) ||
Token::IsRelationalOperator(token_kind) ||
@ -4270,7 +4256,7 @@ class InstanceCallInstr : public InstanceCallBaseInstr {
const InstructionSource& source,
const String& function_name,
Token::Kind token_kind,
InputsArray* arguments,
InputsArray&& arguments,
intptr_t type_args_len,
const Array& argument_names,
intptr_t checked_argument_count,
@ -4282,7 +4268,7 @@ class InstanceCallInstr : public InstanceCallBaseInstr {
source,
function_name,
token_kind,
arguments,
std::move(arguments),
type_args_len,
argument_names,
GetICData(ic_data_array, deopt_id, /*is_static_call=*/false),
@ -4295,7 +4281,7 @@ class InstanceCallInstr : public InstanceCallBaseInstr {
const InstructionSource& source,
const String& function_name,
Token::Kind token_kind,
InputsArray* arguments,
InputsArray&& arguments,
intptr_t type_args_len,
const Array& argument_names,
intptr_t checked_argument_count,
@ -4305,7 +4291,7 @@ class InstanceCallInstr : public InstanceCallBaseInstr {
: InstanceCallBaseInstr(source,
function_name,
token_kind,
arguments,
std::move(arguments),
type_args_len,
argument_names,
/*ic_data=*/nullptr,
@ -4358,14 +4344,14 @@ class PolymorphicInstanceCallInstr : public InstanceCallBaseInstr {
const CallTargets& targets,
bool complete) {
ASSERT(!call->HasPushArguments());
InputsArray* args = new (zone) InputsArray(zone, call->ArgumentCount());
InputsArray args(zone, call->ArgumentCount());
for (intptr_t i = 0, n = call->ArgumentCount(); i < n; ++i) {
args->Add(call->ArgumentValueAt(i)->CopyWithType(zone));
args.Add(call->ArgumentValueAt(i)->CopyWithType(zone));
}
auto new_call = new (zone) PolymorphicInstanceCallInstr(
call->source(), call->function_name(), call->token_kind(), args,
call->type_args_len(), call->argument_names(), call->ic_data(),
call->deopt_id(), call->interface_target(),
call->source(), call->function_name(), call->token_kind(),
std::move(args), call->type_args_len(), call->argument_names(),
call->ic_data(), call->deopt_id(), call->interface_target(),
call->tearoff_interface_target(), targets, complete);
new_call->set_result_type(call->result_type());
new_call->set_entry_kind(call->entry_kind());
@ -4412,7 +4398,7 @@ class PolymorphicInstanceCallInstr : public InstanceCallBaseInstr {
PolymorphicInstanceCallInstr(const InstructionSource& source,
const String& function_name,
Token::Kind token_kind,
InputsArray* arguments,
InputsArray&& arguments,
intptr_t type_args_len,
const Array& argument_names,
const ICData* ic_data,
@ -4424,7 +4410,7 @@ class PolymorphicInstanceCallInstr : public InstanceCallBaseInstr {
: InstanceCallBaseInstr(source,
function_name,
token_kind,
arguments,
std::move(arguments),
type_args_len,
argument_names,
ic_data,
@ -4454,19 +4440,19 @@ class DispatchTableCallInstr : public TemplateDartCall<1> {
DispatchTableCallInstr(const InstructionSource& source,
const Function& interface_target,
const compiler::TableSelector* selector,
InputsArray* arguments,
InputsArray&& arguments,
intptr_t type_args_len,
const Array& argument_names)
: TemplateDartCall(DeoptId::kNone,
type_args_len,
argument_names,
arguments,
std::move(arguments),
source),
interface_target_(interface_target),
selector_(selector) {
ASSERT(selector != nullptr);
ASSERT(interface_target_.IsNotTemporaryScopedHandle());
ASSERT(!arguments->is_empty());
ASSERT(InputCount() > 0);
}
static DispatchTableCallInstr* FromCall(
@ -4839,14 +4825,14 @@ class StaticCallInstr : public TemplateDartCall<0> {
const Function& function,
intptr_t type_args_len,
const Array& argument_names,
InputsArray* arguments,
InputsArray&& arguments,
const ZoneGrowableArray<const ICData*>& ic_data_array,
intptr_t deopt_id,
ICData::RebindRule rebind_rule)
: TemplateDartCall(deopt_id,
type_args_len,
argument_names,
arguments,
std::move(arguments),
source),
ic_data_(GetICData(ic_data_array, deopt_id, /*is_static_call=*/true)),
call_count_(0),
@ -4863,14 +4849,14 @@ class StaticCallInstr : public TemplateDartCall<0> {
const Function& function,
intptr_t type_args_len,
const Array& argument_names,
InputsArray* arguments,
InputsArray&& arguments,
intptr_t deopt_id,
intptr_t call_count,
ICData::RebindRule rebind_rule)
: TemplateDartCall(deopt_id,
type_args_len,
argument_names,
arguments,
std::move(arguments),
source),
ic_data_(NULL),
call_count_(call_count),
@ -4891,13 +4877,13 @@ class StaticCallInstr : public TemplateDartCall<0> {
const Function& target,
intptr_t call_count) {
ASSERT(!call->HasPushArguments());
InputsArray* args = new (zone) InputsArray(zone, call->ArgumentCount());
InputsArray args(zone, call->ArgumentCount());
for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
args->Add(call->ArgumentValueAt(i)->CopyWithType());
args.Add(call->ArgumentValueAt(i)->CopyWithType());
}
StaticCallInstr* new_call = new (zone) StaticCallInstr(
call->source(), target, call->type_args_len(), call->argument_names(),
args, call->deopt_id(), call_count, ICData::kNoRebind);
std::move(args), call->deopt_id(), call_count, ICData::kNoRebind);
if (call->result_type() != NULL) {
new_call->result_type_ = call->result_type();
}
@ -5192,8 +5178,12 @@ class NativeCallInstr : public TemplateDartCall<0> {
const Function& function,
bool link_lazily,
const InstructionSource& source,
InputsArray* args)
: TemplateDartCall(DeoptId::kNone, 0, Array::null_array(), args, source),
InputsArray&& args)
: TemplateDartCall(DeoptId::kNone,
0,
Array::null_array(),
std::move(args),
source),
native_name_(name),
function_(function),
native_c_function_(NULL),
@ -5254,15 +5244,14 @@ class NativeCallInstr : public TemplateDartCall<0> {
// - The arguments to the native call, marshalled in IL as far as possible.
// - The argument address.
// - A TypedData for the return value to populate in machine code (optional).
class FfiCallInstr : public VariadicDefinitionWithEmbeddedInputs {
class FfiCallInstr : public VariadicDefinition {
public:
FfiCallInstr(intptr_t deopt_id,
const compiler::ffi::CallMarshaller& marshaller,
bool is_leaf)
: VariadicDefinitionWithEmbeddedInputs(
marshaller.NumDefinitions() + 1 +
(marshaller.PassTypedData() ? 1 : 0),
deopt_id),
: VariadicDefinition(marshaller.NumDefinitions() + 1 +
(marshaller.PassTypedData() ? 1 : 0),
deopt_id),
marshaller_(marshaller),
is_leaf_(is_leaf) {}
@ -5334,7 +5323,7 @@ class CCallInstr : public VariadicDefinition {
public:
CCallInstr(
const compiler::ffi::NativeCallingConvention& native_calling_convention,
InputsArray* inputs);
InputsArray&& inputs);
DECLARE_INSTRUCTION(CCall)
@ -6506,8 +6495,8 @@ class MaterializeObjectInstr : public VariadicDefinition {
const Class& cls,
intptr_t num_elements,
const ZoneGrowableArray<const Slot*>& slots,
ZoneGrowableArray<Value*>* values)
: VariadicDefinition(values),
InputsArray&& values)
: VariadicDefinition(std::move(values)),
allocation_(allocation),
cls_(cls),
num_elements_(num_elements),
@ -6515,7 +6504,7 @@ class MaterializeObjectInstr : public VariadicDefinition {
locations_(nullptr),
visited_for_liveness_(false),
registers_remapped_(false) {
ASSERT(slots_.length() == values->length());
ASSERT(slots_.length() == InputCount());
}
AllocationInstr* allocation() const { return allocation_; }
@ -8652,7 +8641,7 @@ class FloatToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> {
// TODO(sjindel): Replace with FFICallInstr.
class InvokeMathCFunctionInstr : public VariadicDefinition {
public:
InvokeMathCFunctionInstr(ZoneGrowableArray<Value*>* inputs,
InvokeMathCFunctionInstr(InputsArray&& inputs,
intptr_t deopt_id,
MethodRecognizer::Kind recognized_kind,
const InstructionSource& source);

View file

@ -4,6 +4,8 @@
#include "vm/compiler/backend/redundancy_elimination.h"
#include <utility>
#include "vm/bit_vector.h"
#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/il.h"
@ -3730,8 +3732,7 @@ void AllocationSinking::CreateMaterializationAt(
Instruction* exit,
Definition* alloc,
const ZoneGrowableArray<const Slot*>& slots) {
ZoneGrowableArray<Value*>* values =
new (Z) ZoneGrowableArray<Value*>(slots.length());
InputsArray values(slots.length());
// All loads should be inserted before the first materialization so that
// IR follows the following pattern: loads, materializations, deoptimizing
@ -3766,7 +3767,7 @@ void AllocationSinking::CreateMaterializationAt(
new (Z) LoadFieldInstr(new (Z) Value(alloc), *slot, alloc->source());
}
flow_graph_->InsertBefore(load_point, load, nullptr, FlowGraph::kValue);
values->Add(new (Z) Value(load));
values.Add(new (Z) Value(load));
}
const Class* cls = nullptr;
@ -3794,7 +3795,7 @@ void AllocationSinking::CreateMaterializationAt(
UNREACHABLE();
}
MaterializeObjectInstr* mat = new (Z) MaterializeObjectInstr(
alloc->AsAllocation(), *cls, num_elements, slots, values);
alloc->AsAllocation(), *cls, num_elements, slots, std::move(values));
flow_graph_->InsertBefore(exit, mat, nullptr, FlowGraph::kValue);

View file

@ -5,6 +5,7 @@
#include "vm/compiler/backend/redundancy_elimination.h"
#include <functional>
#include <utility>
#include "vm/compiler/backend/block_builder.h"
#include "vm/compiler/backend/il_printer.h"
@ -271,14 +272,14 @@ static void TestAliasingViaRedefinition(
v1 = builder.AddDefinition(
new LoadFieldInstr(new Value(v0), slot, InstructionSource()));
auto v2 = builder.AddDefinition(make_redefinition(&S, H.flow_graph(), v0));
auto args = new InputsArray(2);
args->Add(new Value(v1));
InputsArray args(2);
args.Add(new Value(v1));
if (make_it_escape) {
args->Add(new Value(v2));
args.Add(new Value(v2));
}
call = builder.AddInstruction(new StaticCallInstr(
InstructionSource(), blackhole, 0, Array::empty_array(), args,
S.GetNextDeoptId(), 0, ICData::RebindRule::kStatic));
InstructionSource(), blackhole, 0, Array::empty_array(),
std::move(args), S.GetNextDeoptId(), 0, ICData::RebindRule::kStatic));
v4 = builder.AddDefinition(
new LoadFieldInstr(new Value(v2), slot, InstructionSource()));
ret = builder.AddInstruction(new ReturnInstr(
@ -452,21 +453,21 @@ static void TestAliasingViaStore(
v1 = builder.AddDefinition(
new LoadFieldInstr(new Value(v0), slot, InstructionSource()));
auto v2 = builder.AddDefinition(make_redefinition(&S, H.flow_graph(), v5));
auto args = new InputsArray(2);
args->Add(new Value(v1));
InputsArray args(2);
args.Add(new Value(v1));
if (make_it_escape) {
auto v6 = builder.AddDefinition(
new LoadFieldInstr(new Value(v2), slot, InstructionSource()));
args->Add(new Value(v6));
args.Add(new Value(v6));
} else if (make_host_escape) {
builder.AddInstruction(
new StoreFieldInstr(slot, new Value(v2), new Value(v0),
kEmitStoreBarrier, InstructionSource()));
args->Add(new Value(v5));
args.Add(new Value(v5));
}
call = builder.AddInstruction(new StaticCallInstr(
InstructionSource(), blackhole, 0, Array::empty_array(), args,
S.GetNextDeoptId(), 0, ICData::RebindRule::kStatic));
InstructionSource(), blackhole, 0, Array::empty_array(),
std::move(args), S.GetNextDeoptId(), 0, ICData::RebindRule::kStatic));
v4 = builder.AddDefinition(
new LoadFieldInstr(new Value(v0), slot, InstructionSource()));
ret = builder.AddInstruction(new ReturnInstr(
@ -605,8 +606,8 @@ ISOLATE_UNIT_TEST_CASE(LoadOptimizer_AliasingViaTypedDataAndUntaggedTypedData) {
// array <- StaticCall(...) {_Uint32List}
array = builder.AddDefinition(new StaticCallInstr(
InstructionSource(), function, 0, Array::empty_array(),
new InputsArray(), DeoptId::kNone, 0, ICData::kNoRebind));
InstructionSource(), function, 0, Array::empty_array(), InputsArray(),
DeoptId::kNone, 0, ICData::kNoRebind));
array->UpdateType(CompileType::FromCid(kTypedDataUint32ArrayCid));
array->SetResultType(zone, CompileType::FromCid(kTypedDataUint32ArrayCid));
array->set_is_known_list_constructor(true);
@ -1425,13 +1426,13 @@ ISOLATE_UNIT_TEST_CASE(CSE_Redefinitions) {
load2 = builder.AddDefinition(
new LoadFieldInstr(new Value(redef3), slot, InstructionSource()));
auto args = new InputsArray(3);
args->Add(new Value(load0));
args->Add(new Value(load1));
args->Add(new Value(load2));
InputsArray args(3);
args.Add(new Value(load0));
args.Add(new Value(load1));
args.Add(new Value(load2));
call = builder.AddInstruction(new StaticCallInstr(
InstructionSource(), blackhole, 0, Array::empty_array(), args,
S.GetNextDeoptId(), 0, ICData::RebindRule::kStatic));
InstructionSource(), blackhole, 0, Array::empty_array(),
std::move(args), S.GetNextDeoptId(), 0, ICData::RebindRule::kStatic));
ret = builder.AddReturn(new Value(box1));
}

View file

@ -236,7 +236,7 @@ ISOLATE_UNIT_TEST_CASE(TypePropagator_Refinement) {
new StaticCallInstr(InstructionSource(), target_func,
/*type_args_len=*/0,
/*argument_names=*/Array::empty_array(),
new InputsArray(0), S.GetNextDeoptId(),
InputsArray(0), S.GetNextDeoptId(),
/*call_count=*/0, ICData::RebindRule::kStatic));
builder.AddInstruction(new GotoInstr(b4, S.GetNextDeoptId()));
}

View file

@ -4,6 +4,8 @@
#include "vm/compiler/frontend/base_flow_graph_builder.h"
#include <utility>
#include "vm/compiler/backend/range_analysis.h" // For Range.
#include "vm/compiler/ffi/call.h"
#include "vm/compiler/frontend/flow_graph_builder.h" // For InlineExitCollector.
@ -808,11 +810,11 @@ IndirectEntryInstr* BaseFlowGraphBuilder::BuildIndirectEntry(
GetNextDeoptId());
}
InputsArray* BaseFlowGraphBuilder::GetArguments(int count) {
InputsArray* arguments = new (Z) ZoneGrowableArray<Value*>(Z, count);
arguments->SetLength(count);
InputsArray BaseFlowGraphBuilder::GetArguments(int count) {
InputsArray arguments(Z, count);
arguments.SetLength(count);
for (intptr_t i = count - 1; i >= 0; --i) {
arguments->data()[i] = Pop();
arguments[i] = Pop();
}
return arguments;
}
@ -1180,10 +1182,10 @@ Fragment BaseFlowGraphBuilder::ClosureCall(TokenPosition position,
const intptr_t total_count =
(type_args_len > 0 ? 1 : 0) + argument_count +
/*closure (bare instructions) or function (otherwise)*/ 1;
InputsArray* arguments = GetArguments(total_count);
ClosureCallInstr* call =
new (Z) ClosureCallInstr(arguments, type_args_len, argument_names,
InstructionSource(position), GetNextDeoptId());
InputsArray arguments = GetArguments(total_count);
ClosureCallInstr* call = new (Z)
ClosureCallInstr(std::move(arguments), type_args_len, argument_names,
InstructionSource(position), GetNextDeoptId());
Push(call);
result <<= call;
return result;
@ -1236,10 +1238,10 @@ Fragment BaseFlowGraphBuilder::InitConstantParameters() {
Fragment BaseFlowGraphBuilder::InvokeMathCFunction(
MethodRecognizer::Kind recognized_kind,
intptr_t num_inputs) {
InputsArray* args = GetArguments(num_inputs);
auto* instr = new (Z)
InvokeMathCFunctionInstr(args, GetNextDeoptId(), recognized_kind,
InstructionSource(TokenPosition::kNoSource));
InputsArray args = GetArguments(num_inputs);
auto* instr = new (Z) InvokeMathCFunctionInstr(
std::move(args), GetNextDeoptId(), recognized_kind,
InstructionSource(TokenPosition::kNoSource));
Push(instr);
return Fragment(instr);
}

View file

@ -264,7 +264,7 @@ class BaseFlowGraphBuilder {
LocalVariable* MakeTemporary(const char* suffix = nullptr);
Fragment DropTemporary(LocalVariable** temp);
InputsArray* GetArguments(int count);
InputsArray GetArguments(int count);
TargetEntryInstr* BuildTargetEntry();
FunctionEntryInstr* BuildFunctionEntry(GraphEntryInstr* graph_entry);

View file

@ -4,6 +4,8 @@
#include "vm/compiler/frontend/kernel_to_il.h"
#include <utility>
#include "platform/assert.h"
#include "platform/globals.h"
#include "vm/class_id.h"
@ -356,11 +358,11 @@ Fragment FlowGraphBuilder::InstanceCall(
bool receiver_is_not_smi,
bool is_call_on_this) {
const intptr_t total_count = argument_count + (type_args_len > 0 ? 1 : 0);
InputsArray* arguments = GetArguments(total_count);
InputsArray arguments = GetArguments(total_count);
InstanceCallInstr* call = new (Z) InstanceCallInstr(
InstructionSource(position), name, kind, arguments, type_args_len,
argument_names, checked_argument_count, ic_data_array_, GetNextDeoptId(),
interface_target, tearoff_interface_target);
InstructionSource(position), name, kind, std::move(arguments),
type_args_len, argument_names, checked_argument_count, ic_data_array_,
GetNextDeoptId(), interface_target, tearoff_interface_target);
if ((result_type != NULL) && !result_type->IsTrivial()) {
call->SetResultType(Z, result_type->ToCompileType(Z));
}
@ -413,12 +415,13 @@ Fragment FlowGraphBuilder::CCall(
const intptr_t num_arguments =
native_calling_convention.argument_locations().length() + 1;
InputsArray* arguments = new (Z) InputsArray(num_arguments);
arguments->FillWith(nullptr, 0, num_arguments);
InputsArray arguments(num_arguments);
arguments.FillWith(nullptr, 0, num_arguments);
for (intptr_t i = num_arguments - 1; i >= 0; --i) {
(*arguments)[i] = Pop();
arguments[i] = Pop();
}
auto* const call = new (Z) CCallInstr(native_calling_convention, arguments);
auto* const call =
new (Z) CCallInstr(native_calling_convention, std::move(arguments));
Push(call);
body <<= call;
@ -562,10 +565,10 @@ Fragment FlowGraphBuilder::NativeCall(const String& name,
InlineBailout("kernel::FlowGraphBuilder::NativeCall");
const intptr_t num_args =
function.NumParameters() + (function.IsGeneric() ? 1 : 0);
InputsArray* arguments = GetArguments(num_args);
NativeCallInstr* call = new (Z)
NativeCallInstr(name, function, FLAG_link_natives_lazily,
InstructionSource(function.end_token_pos()), arguments);
InputsArray arguments = GetArguments(num_args);
NativeCallInstr* call = new (Z) NativeCallInstr(
name, function, FLAG_link_natives_lazily,
InstructionSource(function.end_token_pos()), std::move(arguments));
Push(call);
return Fragment(call);
}
@ -625,10 +628,10 @@ Fragment FlowGraphBuilder::StaticCall(TokenPosition position,
intptr_t type_args_count,
bool use_unchecked_entry) {
const intptr_t total_count = argument_count + (type_args_count > 0 ? 1 : 0);
InputsArray* arguments = GetArguments(total_count);
InputsArray arguments = GetArguments(total_count);
StaticCallInstr* call = new (Z) StaticCallInstr(
InstructionSource(position), target, type_args_count, argument_names,
arguments, ic_data_array_, GetNextDeoptId(), rebind_rule);
std::move(arguments), ic_data_array_, GetNextDeoptId(), rebind_rule);
SetResultTypeForStaticCall(call, target, argument_count, result_type);
if (use_unchecked_entry) {
call->set_entry_kind(Code::EntryKind::kUnchecked);

View file

@ -29,6 +29,11 @@ class GrowableArray : public BaseGrowableArray<T, ValueObject, Zone> {
GrowableArray()
: BaseGrowableArray<T, ValueObject, Zone>(
ASSERT_NOTNULL(ThreadState::Current()->zone())) {}
GrowableArray(GrowableArray&& other) = default;
GrowableArray& operator=(GrowableArray&& other) = default;
~GrowableArray() = default;
DISALLOW_COPY_AND_ASSIGN(GrowableArray);
};
template <typename T>
@ -44,6 +49,11 @@ class ZoneGrowableArray : public BaseGrowableArray<T, ZoneAllocated, Zone> {
ZoneGrowableArray()
: BaseGrowableArray<T, ZoneAllocated, Zone>(
ASSERT_NOTNULL(ThreadState::Current()->zone())) {}
ZoneGrowableArray(ZoneGrowableArray&& other) = default;
ZoneGrowableArray& operator=(ZoneGrowableArray&& other) = default;
~ZoneGrowableArray() = default;
DISALLOW_COPY_AND_ASSIGN(ZoneGrowableArray);
};
// T must be a Handle type.

View file

@ -6,6 +6,8 @@
#include "vm/regexp_assembler_ir.h"
#include <utility>
#include "platform/unicode.h"
#include "vm/bit_vector.h"
#include "vm/compiler/backend/il_printer.h"
@ -426,18 +428,18 @@ ComparisonInstr* IRRegExpMacroAssembler::Comparison(ComparisonKind kind,
StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
const Function& function,
ICData::RebindRule rebind_rule) const {
InputsArray* arguments = new (Z) InputsArray(Z, 0);
return StaticCall(function, arguments, rebind_rule);
InputsArray arguments(Z, 0);
return StaticCall(function, std::move(arguments), rebind_rule);
}
StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
const Function& function,
Value* arg1,
ICData::RebindRule rebind_rule) const {
InputsArray* arguments = new (Z) InputsArray(Z, 1);
arguments->Add(arg1);
InputsArray arguments(Z, 1);
arguments.Add(arg1);
return StaticCall(function, arguments, rebind_rule);
return StaticCall(function, std::move(arguments), rebind_rule);
}
StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
@ -445,41 +447,41 @@ StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
Value* arg1,
Value* arg2,
ICData::RebindRule rebind_rule) const {
InputsArray* arguments = new (Z) InputsArray(Z, 2);
arguments->Add(arg1);
arguments->Add(arg2);
InputsArray arguments(Z, 2);
arguments.Add(arg1);
arguments.Add(arg2);
return StaticCall(function, arguments, rebind_rule);
return StaticCall(function, std::move(arguments), rebind_rule);
}
StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
const Function& function,
InputsArray* arguments,
InputsArray&& arguments,
ICData::RebindRule rebind_rule) const {
const intptr_t kTypeArgsLen = 0;
return new (Z) StaticCallInstr(InstructionSource(), function, kTypeArgsLen,
Object::null_array(), arguments,
Object::null_array(), std::move(arguments),
ic_data_array_, GetNextDeoptId(), rebind_rule);
}
InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall(
const InstanceCallDescriptor& desc,
Value* arg1) const {
InputsArray* arguments = new (Z) InputsArray(Z, 1);
arguments->Add(arg1);
InputsArray arguments(Z, 1);
arguments.Add(arg1);
return InstanceCall(desc, arguments);
return InstanceCall(desc, std::move(arguments));
}
InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall(
const InstanceCallDescriptor& desc,
Value* arg1,
Value* arg2) const {
InputsArray* arguments = new (Z) InputsArray(Z, 2);
arguments->Add(arg1);
arguments->Add(arg2);
InputsArray arguments(Z, 2);
arguments.Add(arg1);
arguments.Add(arg2);
return InstanceCall(desc, arguments);
return InstanceCall(desc, std::move(arguments));
}
InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall(
@ -487,22 +489,22 @@ InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall(
Value* arg1,
Value* arg2,
Value* arg3) const {
InputsArray* arguments = new (Z) InputsArray(Z, 3);
arguments->Add(arg1);
arguments->Add(arg2);
arguments->Add(arg3);
InputsArray arguments(Z, 3);
arguments.Add(arg1);
arguments.Add(arg2);
arguments.Add(arg3);
return InstanceCall(desc, arguments);
return InstanceCall(desc, std::move(arguments));
}
InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall(
const InstanceCallDescriptor& desc,
InputsArray* arguments) const {
InputsArray&& arguments) const {
const intptr_t kTypeArgsLen = 0;
return new (Z) InstanceCallInstr(
InstructionSource(), desc.name, desc.token_kind, arguments, kTypeArgsLen,
Object::null_array(), desc.checked_argument_count, ic_data_array_,
GetNextDeoptId());
InstructionSource(), desc.name, desc.token_kind, std::move(arguments),
kTypeArgsLen, Object::null_array(), desc.checked_argument_count,
ic_data_array_, GetNextDeoptId());
}
LoadLocalInstr* IRRegExpMacroAssembler::LoadLocal(LocalVariable* local) const {

View file

@ -243,7 +243,7 @@ class IRRegExpMacroAssembler : public RegExpMacroAssembler {
Value* arg2,
Value* arg3) const;
InstanceCallInstr* InstanceCall(const InstanceCallDescriptor& desc,
InputsArray* arguments) const;
InputsArray&& arguments) const;
StaticCallInstr* StaticCall(const Function& function,
ICData::RebindRule rebind_rule) const;
@ -255,7 +255,7 @@ class IRRegExpMacroAssembler : public RegExpMacroAssembler {
Value* arg2,
ICData::RebindRule rebind_rule) const;
StaticCallInstr* StaticCall(const Function& function,
InputsArray* arguments,
InputsArray&& arguments,
ICData::RebindRule rebind_rule) const;
// Creates a new block consisting simply of a goto to dst.