From 964c756faafa16a857d1d2c271258b3be2a9e546 Mon Sep 17 00:00:00 2001 From: Alexander Markov Date: Mon, 8 Aug 2022 15:58:40 +0000 Subject: [PATCH] [vm/compiler] Unify VariadicDefinition and VariadicDefinitionWithEmbeddedInputs The unified base class for instructions with variable number of inputs now keeps inputs in GrowableArray (no indirection, no extra zone memory allocation). InputsArray is changed to GrowableArray 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 Reviewed-by: Martin Kustermann --- .../vm/compiler/aot/aot_call_specializer.cc | 57 +++---- runtime/vm/compiler/backend/il.cc | 24 +-- runtime/vm/compiler/backend/il.h | 141 ++++++++---------- .../backend/redundancy_elimination.cc | 9 +- .../backend/redundancy_elimination_test.cc | 39 ++--- .../compiler/backend/type_propagator_test.cc | 2 +- .../frontend/base_flow_graph_builder.cc | 26 ++-- .../frontend/base_flow_graph_builder.h | 2 +- runtime/vm/compiler/frontend/kernel_to_il.cc | 31 ++-- runtime/vm/growable_array.h | 10 ++ runtime/vm/regexp_assembler_ir.cc | 56 +++---- runtime/vm/regexp_assembler_ir.h | 4 +- 12 files changed, 206 insertions(+), 195 deletions(-) diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc index 526a2c8b7d8..0baf6d26930 100644 --- a/runtime/vm/compiler/aot/aot_call_specializer.cc +++ b/runtime/vm/compiler/aot/aot_call_specializer.cc @@ -4,6 +4,8 @@ #include "vm/compiler/aot/aot_call_specializer.h" +#include + #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(); diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc index 5330a4e69ea..9545e07e9ab 100644 --- a/runtime/vm/compiler/backend/il.cc +++ b/runtime/vm/compiler/backend/il.cc @@ -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* 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 } diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h index a9e3066818a..c218f8665e8 100644 --- a/runtime/vm/compiler/backend/il.h +++ b/runtime/vm/compiler/backend/il.h @@ -780,7 +780,7 @@ class BinaryFeedback : public ZoneAllocated { friend class Cids; }; -typedef ZoneGrowableArray InputsArray; +typedef GrowableArray InputsArray; typedef ZoneGrowableArray PushArgumentsArray; template @@ -2534,43 +2534,29 @@ class TemplateDefinition : public CSETrait::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 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& 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& slots, - ZoneGrowableArray* 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* inputs, + InvokeMathCFunctionInstr(InputsArray&& inputs, intptr_t deopt_id, MethodRecognizer::Kind recognized_kind, const InstructionSource& source); diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc index f9355fc70ef..c1925000f52 100644 --- a/runtime/vm/compiler/backend/redundancy_elimination.cc +++ b/runtime/vm/compiler/backend/redundancy_elimination.cc @@ -4,6 +4,8 @@ #include "vm/compiler/backend/redundancy_elimination.h" +#include + #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& slots) { - ZoneGrowableArray* values = - new (Z) ZoneGrowableArray(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); diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc index 63276b1cd27..853d4ef5f16 100644 --- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc +++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc @@ -5,6 +5,7 @@ #include "vm/compiler/backend/redundancy_elimination.h" #include +#include #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)); } diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc index 2f18be4d8f7..899e4850185 100644 --- a/runtime/vm/compiler/backend/type_propagator_test.cc +++ b/runtime/vm/compiler/backend/type_propagator_test.cc @@ -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())); } diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc index 7cd28de698f..1d475167831 100644 --- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc +++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc @@ -4,6 +4,8 @@ #include "vm/compiler/frontend/base_flow_graph_builder.h" +#include + #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(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); } diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h index a91212e4f1e..ab19fdd28e6 100644 --- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h +++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h @@ -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); diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc index 66de960259f..311179d5b59 100644 --- a/runtime/vm/compiler/frontend/kernel_to_il.cc +++ b/runtime/vm/compiler/frontend/kernel_to_il.cc @@ -4,6 +4,8 @@ #include "vm/compiler/frontend/kernel_to_il.h" +#include + #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); diff --git a/runtime/vm/growable_array.h b/runtime/vm/growable_array.h index 84e378d372a..b1f8a2600dd 100644 --- a/runtime/vm/growable_array.h +++ b/runtime/vm/growable_array.h @@ -29,6 +29,11 @@ class GrowableArray : public BaseGrowableArray { GrowableArray() : BaseGrowableArray( ASSERT_NOTNULL(ThreadState::Current()->zone())) {} + + GrowableArray(GrowableArray&& other) = default; + GrowableArray& operator=(GrowableArray&& other) = default; + ~GrowableArray() = default; + DISALLOW_COPY_AND_ASSIGN(GrowableArray); }; template @@ -44,6 +49,11 @@ class ZoneGrowableArray : public BaseGrowableArray { ZoneGrowableArray() : BaseGrowableArray( 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. diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc index 36c5414087d..2e7a7b4184e 100644 --- a/runtime/vm/regexp_assembler_ir.cc +++ b/runtime/vm/regexp_assembler_ir.cc @@ -6,6 +6,8 @@ #include "vm/regexp_assembler_ir.h" +#include + #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 { diff --git a/runtime/vm/regexp_assembler_ir.h b/runtime/vm/regexp_assembler_ir.h index d52128dc74e..cbdcf3d59d6 100644 --- a/runtime/vm/regexp_assembler_ir.h +++ b/runtime/vm/regexp_assembler_ir.h @@ -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.