mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +00:00
[vm/compiler] More consistent handling of inputs of IL instructions
This change removes duplicate management of inputs in variadic IL instructions by introducing VariadicDefinition and VariadicDefinitionWithEmbeddedInputs base classes. TemplateInstruction and TemplateDefinition are used in more places where appropriate. Number of inputs no longer depends on the values of the inputs (DropTempsInstr and AllocateObjectInstr). This change also prepares IL for the future implementation of binary serialization/deserialization in the following ways: * Environment now holds Function and not ParsedFunction (which are not going to be serialized). * Instructions no longer keep Zone* pointer (it's redundant). * NativeCallInstr keeps references to handles instead of pointers. TEST=ci (pure refactoring) Change-Id: I932b62c1c207bbf60cddbded8a39b41beabd3e83 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253480 Reviewed-by: Slava Egorov <vegorov@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
d94a1cd419
commit
63e170a242
|
@ -24,8 +24,7 @@ class BlockBuilder : public ValueObject {
|
||||||
flow_graph->inlining_id())),
|
flow_graph->inlining_id())),
|
||||||
entry_(entry),
|
entry_(entry),
|
||||||
current_(entry),
|
current_(entry),
|
||||||
dummy_env_(
|
dummy_env_(new Environment(0, 0, 0, flow_graph->function(), nullptr)) {
|
||||||
new Environment(0, 0, 0, flow_graph->parsed_function(), nullptr)) {
|
|
||||||
// Some graph transformations use environments from block entries.
|
// Some graph transformations use environments from block entries.
|
||||||
entry->SetEnvironment(dummy_env_);
|
entry->SetEnvironment(dummy_env_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5867,9 +5867,9 @@ Environment* Environment::From(Zone* zone,
|
||||||
intptr_t fixed_parameter_count,
|
intptr_t fixed_parameter_count,
|
||||||
intptr_t lazy_deopt_pruning_count,
|
intptr_t lazy_deopt_pruning_count,
|
||||||
const ParsedFunction& parsed_function) {
|
const ParsedFunction& parsed_function) {
|
||||||
Environment* env =
|
Environment* env = new (zone)
|
||||||
new (zone) Environment(definitions.length(), fixed_parameter_count,
|
Environment(definitions.length(), fixed_parameter_count,
|
||||||
lazy_deopt_pruning_count, parsed_function, NULL);
|
lazy_deopt_pruning_count, parsed_function.function(), NULL);
|
||||||
for (intptr_t i = 0; i < definitions.length(); ++i) {
|
for (intptr_t i = 0; i < definitions.length(); ++i) {
|
||||||
env->values_.Add(new (zone) Value(definitions[i]));
|
env->values_.Add(new (zone) Value(definitions[i]));
|
||||||
}
|
}
|
||||||
|
@ -5882,9 +5882,9 @@ void Environment::PushValue(Value* value) {
|
||||||
|
|
||||||
Environment* Environment::DeepCopy(Zone* zone, intptr_t length) const {
|
Environment* Environment::DeepCopy(Zone* zone, intptr_t length) const {
|
||||||
ASSERT(length <= values_.length());
|
ASSERT(length <= values_.length());
|
||||||
Environment* copy = new (zone) Environment(
|
Environment* copy = new (zone)
|
||||||
length, fixed_parameter_count_, LazyDeoptPruneCount(), parsed_function_,
|
Environment(length, fixed_parameter_count_, LazyDeoptPruneCount(),
|
||||||
(outer_ == NULL) ? NULL : outer_->DeepCopy(zone));
|
function_, (outer_ == NULL) ? NULL : outer_->DeepCopy(zone));
|
||||||
copy->SetDeoptId(DeoptIdBits::decode(bitfield_));
|
copy->SetDeoptId(DeoptIdBits::decode(bitfield_));
|
||||||
copy->SetLazyDeoptToBeforeDeoptId(LazyDeoptToBeforeDeoptId());
|
copy->SetLazyDeoptToBeforeDeoptId(LazyDeoptToBeforeDeoptId());
|
||||||
if (locations_ != NULL) {
|
if (locations_ != NULL) {
|
||||||
|
@ -6355,16 +6355,10 @@ InvokeMathCFunctionInstr::InvokeMathCFunctionInstr(
|
||||||
intptr_t deopt_id,
|
intptr_t deopt_id,
|
||||||
MethodRecognizer::Kind recognized_kind,
|
MethodRecognizer::Kind recognized_kind,
|
||||||
const InstructionSource& source)
|
const InstructionSource& source)
|
||||||
: PureDefinition(source, deopt_id),
|
: VariadicDefinition(inputs, source, deopt_id),
|
||||||
inputs_(inputs),
|
|
||||||
recognized_kind_(recognized_kind),
|
recognized_kind_(recognized_kind),
|
||||||
token_pos_(source.token_pos) {
|
token_pos_(source.token_pos) {
|
||||||
ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_));
|
ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_));
|
||||||
for (intptr_t i = 0; i < inputs_->length(); ++i) {
|
|
||||||
ASSERT((*inputs)[i] != NULL);
|
|
||||||
(*inputs)[i]->set_instruction(this);
|
|
||||||
(*inputs)[i]->set_use_index(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t InvokeMathCFunctionInstr::ArgumentCountFor(
|
intptr_t InvokeMathCFunctionInstr::ArgumentCountFor(
|
||||||
|
@ -6599,7 +6593,7 @@ void FfiCallInstr::EmitParamMoves(FlowGraphCompiler* compiler,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves for arguments.
|
// Moves for arguments.
|
||||||
compiler::ffi::FrameRebase rebase(zone_, /*old_base=*/FPREG,
|
compiler::ffi::FrameRebase rebase(compiler->zone(), /*old_base=*/FPREG,
|
||||||
/*new_base=*/saved_fp,
|
/*new_base=*/saved_fp,
|
||||||
/*stack_delta=*/0);
|
/*stack_delta=*/0);
|
||||||
intptr_t def_index = 0;
|
intptr_t def_index = 0;
|
||||||
|
@ -6627,7 +6621,8 @@ void FfiCallInstr::EmitParamMoves(FlowGraphCompiler* compiler,
|
||||||
: arg_target.IsMultiple() ? *arg_target.AsMultiple().locations()[i]
|
: arg_target.IsMultiple() ? *arg_target.AsMultiple().locations()[i]
|
||||||
: arg_target.IsPointerToMemory()
|
: arg_target.IsPointerToMemory()
|
||||||
? arg_target.AsPointerToMemory().pointer_location()
|
? arg_target.AsPointerToMemory().pointer_location()
|
||||||
: /*arg_target.IsStack()*/ arg_target.Split(zone_, num_defs, i);
|
: /*arg_target.IsStack()*/ arg_target.Split(compiler->zone(),
|
||||||
|
num_defs, i);
|
||||||
|
|
||||||
ConstantTemporaryAllocator temp_alloc(temp0);
|
ConstantTemporaryAllocator temp_alloc(temp0);
|
||||||
if (origin.IsConstant()) {
|
if (origin.IsConstant()) {
|
||||||
|
@ -6692,8 +6687,8 @@ void FfiCallInstr::EmitParamMoves(FlowGraphCompiler* compiler,
|
||||||
|
|
||||||
// TypedData/Pointer data pointed to in temp.
|
// TypedData/Pointer data pointed to in temp.
|
||||||
const auto& dst = compiler::ffi::NativeRegistersLocation(
|
const auto& dst = compiler::ffi::NativeRegistersLocation(
|
||||||
zone_, pointer_loc.payload_type(), pointer_loc.container_type(),
|
compiler->zone(), pointer_loc.payload_type(),
|
||||||
temp0);
|
pointer_loc.container_type(), temp0);
|
||||||
compiler->EmitNativeMove(dst, pointer_loc, &temp_alloc);
|
compiler->EmitNativeMove(dst, pointer_loc, &temp_alloc);
|
||||||
__ LoadField(temp0,
|
__ LoadField(temp0,
|
||||||
compiler::FieldAddress(
|
compiler::FieldAddress(
|
||||||
|
@ -6715,8 +6710,8 @@ void FfiCallInstr::EmitParamMoves(FlowGraphCompiler* compiler,
|
||||||
__ MoveRegister(temp0, SPREG);
|
__ MoveRegister(temp0, SPREG);
|
||||||
__ AddImmediate(temp0, sp_offset);
|
__ AddImmediate(temp0, sp_offset);
|
||||||
const auto& src = compiler::ffi::NativeRegistersLocation(
|
const auto& src = compiler::ffi::NativeRegistersLocation(
|
||||||
zone_, pointer_loc.payload_type(), pointer_loc.container_type(),
|
compiler->zone(), pointer_loc.payload_type(),
|
||||||
temp0);
|
pointer_loc.container_type(), temp0);
|
||||||
__ Comment("pointer_loc %s <- src %s", pointer_loc.ToCString(),
|
__ Comment("pointer_loc %s <- src %s", pointer_loc.ToCString(),
|
||||||
src.ToCString());
|
src.ToCString());
|
||||||
compiler->EmitNativeMove(pointer_loc, src, &temp_alloc);
|
compiler->EmitNativeMove(pointer_loc, src, &temp_alloc);
|
||||||
|
@ -7001,21 +6996,15 @@ LocationSummary* CCallInstr::MakeLocationSummaryInternal(
|
||||||
}
|
}
|
||||||
|
|
||||||
CCallInstr::CCallInstr(
|
CCallInstr::CCallInstr(
|
||||||
Zone* zone,
|
|
||||||
const compiler::ffi::NativeCallingConvention& native_calling_convention,
|
const compiler::ffi::NativeCallingConvention& native_calling_convention,
|
||||||
InputsArray* inputs)
|
InputsArray* inputs)
|
||||||
: Definition(DeoptId::kNone),
|
: VariadicDefinition(inputs, DeoptId::kNone),
|
||||||
zone_(zone),
|
native_calling_convention_(native_calling_convention) {
|
||||||
native_calling_convention_(native_calling_convention),
|
|
||||||
inputs_(inputs) {
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
const intptr_t num_inputs =
|
const intptr_t num_inputs =
|
||||||
native_calling_convention.argument_locations().length() + 1;
|
native_calling_convention.argument_locations().length() + 1;
|
||||||
ASSERT(num_inputs == inputs->length());
|
ASSERT(num_inputs == inputs->length());
|
||||||
#endif
|
#endif
|
||||||
for (intptr_t i = 0, n = inputs_->length(); i < n; ++i) {
|
|
||||||
SetInputAt(i, (*inputs_)[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Representation CCallInstr::RequiredInputRepresentation(intptr_t idx) const {
|
Representation CCallInstr::RequiredInputRepresentation(intptr_t idx) const {
|
||||||
|
@ -7037,7 +7026,7 @@ void CCallInstr::EmitParamMoves(FlowGraphCompiler* compiler,
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantTemporaryAllocator temp_alloc(temp0);
|
ConstantTemporaryAllocator temp_alloc(temp0);
|
||||||
compiler::ffi::FrameRebase rebase(zone_, /*old_base=*/FPREG,
|
compiler::ffi::FrameRebase rebase(compiler->zone(), /*old_base=*/FPREG,
|
||||||
/*new_base=*/saved_fp,
|
/*new_base=*/saved_fp,
|
||||||
/*stack_delta=*/0);
|
/*stack_delta=*/0);
|
||||||
|
|
||||||
|
|
|
@ -1488,7 +1488,7 @@ class ParallelMoveInstr : public TemplateInstruction<0, NoThrow> {
|
||||||
// predecessors. Targets are all other basic block entries. The types
|
// predecessors. Targets are all other basic block entries. The types
|
||||||
// enforce edge-split form---joins are forbidden as the successors of
|
// enforce edge-split form---joins are forbidden as the successors of
|
||||||
// branches.
|
// branches.
|
||||||
class BlockEntryInstr : public Instruction {
|
class BlockEntryInstr : public TemplateInstruction<0, NoThrow> {
|
||||||
public:
|
public:
|
||||||
virtual intptr_t PredecessorCount() const = 0;
|
virtual intptr_t PredecessorCount() const = 0;
|
||||||
virtual BlockEntryInstr* PredecessorAt(intptr_t index) const = 0;
|
virtual BlockEntryInstr* PredecessorAt(intptr_t index) const = 0;
|
||||||
|
@ -1558,12 +1558,6 @@ class BlockEntryInstr : public Instruction {
|
||||||
GrowableArray<BlockEntryInstr*>* preorder,
|
GrowableArray<BlockEntryInstr*>* preorder,
|
||||||
GrowableArray<intptr_t>* parent);
|
GrowableArray<intptr_t>* parent);
|
||||||
|
|
||||||
virtual intptr_t InputCount() const { return 0; }
|
|
||||||
virtual Value* InputAt(intptr_t i) const {
|
|
||||||
UNREACHABLE();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool CanBecomeDeoptimizationTarget() const {
|
virtual bool CanBecomeDeoptimizationTarget() const {
|
||||||
// BlockEntry environment is copied to Goto and Branch instructions
|
// BlockEntry environment is copied to Goto and Branch instructions
|
||||||
// when we insert new blocks targeting this block.
|
// when we insert new blocks targeting this block.
|
||||||
|
@ -1574,8 +1568,6 @@ class BlockEntryInstr : public Instruction {
|
||||||
|
|
||||||
virtual bool HasUnknownSideEffects() const { return false; }
|
virtual bool HasUnknownSideEffects() const { return false; }
|
||||||
|
|
||||||
virtual bool MayThrow() const { return false; }
|
|
||||||
|
|
||||||
intptr_t try_index() const { return try_index_; }
|
intptr_t try_index() const { return try_index_; }
|
||||||
void set_try_index(intptr_t index) { try_index_ = index; }
|
void set_try_index(intptr_t index) { try_index_ = index; }
|
||||||
|
|
||||||
|
@ -1629,7 +1621,7 @@ class BlockEntryInstr : public Instruction {
|
||||||
intptr_t try_index,
|
intptr_t try_index,
|
||||||
intptr_t deopt_id,
|
intptr_t deopt_id,
|
||||||
intptr_t stack_depth)
|
intptr_t stack_depth)
|
||||||
: Instruction(deopt_id),
|
: TemplateInstruction(deopt_id),
|
||||||
block_id_(block_id),
|
block_id_(block_id),
|
||||||
try_index_(try_index),
|
try_index_(try_index),
|
||||||
stack_depth_(stack_depth),
|
stack_depth_(stack_depth),
|
||||||
|
@ -1642,8 +1634,6 @@ class BlockEntryInstr : public Instruction {
|
||||||
BitVector* block_marks);
|
BitVector* block_marks);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
|
|
||||||
|
|
||||||
virtual void ClearPredecessors() = 0;
|
virtual void ClearPredecessors() = 0;
|
||||||
virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0;
|
virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0;
|
||||||
|
|
||||||
|
@ -2253,17 +2243,6 @@ class AliasIdentity : public ValueObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Parse(const char* str, AliasIdentity* out) {
|
|
||||||
#define VALUE_CASE(name, val) \
|
|
||||||
if (strcmp(str, #name) == 0) { \
|
|
||||||
out->value_ = k##name; \
|
|
||||||
return true; \
|
|
||||||
}
|
|
||||||
FOR_EACH_ALIAS_IDENTITY_VALUE(VALUE_CASE)
|
|
||||||
#undef VALUE_CASE
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsUnknown() const { return value_ == kUnknown; }
|
bool IsUnknown() const { return value_ == kUnknown; }
|
||||||
bool IsAliased() const { return value_ == kAliased; }
|
bool IsAliased() const { return value_ == kAliased; }
|
||||||
bool IsNotAliased() const { return (value_ & kNotAliased) != 0; }
|
bool IsNotAliased() const { return (value_ & kNotAliased) != 0; }
|
||||||
|
@ -2553,18 +2532,67 @@ class TemplateDefinition : public CSETrait<Definition, PureDefinition>::Base {
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
|
virtual void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class PhiInstr : public Definition {
|
class VariadicDefinition : public Definition {
|
||||||
|
public:
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
: 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)
|
||||||
|
: Definition(source, deopt_id), inputs_(num_inputs) {
|
||||||
|
inputs_.EnsureLength(num_inputs, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
intptr_t InputCount() const { return inputs_.length(); }
|
||||||
|
Value* InputAt(intptr_t i) const { return inputs_[i]; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GrowableArray<Value*> inputs_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class PhiInstr : public VariadicDefinitionWithEmbeddedInputs {
|
||||||
public:
|
public:
|
||||||
PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
|
PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
|
||||||
: block_(block),
|
: VariadicDefinitionWithEmbeddedInputs(num_inputs),
|
||||||
inputs_(num_inputs),
|
block_(block),
|
||||||
representation_(kTagged),
|
representation_(kTagged),
|
||||||
is_alive_(false),
|
is_alive_(false),
|
||||||
is_receiver_(kUnknownReceiver) {
|
is_receiver_(kUnknownReceiver) {}
|
||||||
for (intptr_t i = 0; i < num_inputs; ++i) {
|
|
||||||
inputs_.Add(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the block entry for that instruction.
|
// Get the block entry for that instruction.
|
||||||
virtual BlockEntryInstr* GetBlock() { return block(); }
|
virtual BlockEntryInstr* GetBlock() { return block(); }
|
||||||
|
@ -2573,10 +2601,6 @@ class PhiInstr : public Definition {
|
||||||
virtual CompileType ComputeType() const;
|
virtual CompileType ComputeType() const;
|
||||||
virtual bool RecomputeType();
|
virtual bool RecomputeType();
|
||||||
|
|
||||||
intptr_t InputCount() const { return inputs_.length(); }
|
|
||||||
|
|
||||||
Value* InputAt(intptr_t i) const { return inputs_[i]; }
|
|
||||||
|
|
||||||
virtual bool ComputeCanDeoptimize() const { return false; }
|
virtual bool ComputeCanDeoptimize() const { return false; }
|
||||||
|
|
||||||
virtual bool HasUnknownSideEffects() const { return false; }
|
virtual bool HasUnknownSideEffects() const { return false; }
|
||||||
|
@ -2644,10 +2668,7 @@ class PhiInstr : public Definition {
|
||||||
// predecessors.
|
// predecessors.
|
||||||
friend class ConstantPropagator;
|
friend class ConstantPropagator;
|
||||||
|
|
||||||
void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
|
|
||||||
|
|
||||||
JoinEntryInstr* block_;
|
JoinEntryInstr* block_;
|
||||||
GrowableArray<Value*> inputs_;
|
|
||||||
Representation representation_;
|
Representation representation_;
|
||||||
BitVector* reaching_defs_ = nullptr;
|
BitVector* reaching_defs_ = nullptr;
|
||||||
bool is_alive_;
|
bool is_alive_;
|
||||||
|
@ -2663,7 +2684,7 @@ class PhiInstr : public Definition {
|
||||||
// (0 is the very first parameter, 1 is next and so on). When [base_reg] is
|
// (0 is the very first parameter, 1 is next and so on). When [base_reg] is
|
||||||
// set to SPREG, value [index] needs to be reversed (0 is the very last
|
// set to SPREG, value [index] needs to be reversed (0 is the very last
|
||||||
// parameter, 1 is next and so on) to get the sp relative position.
|
// parameter, 1 is next and so on) to get the sp relative position.
|
||||||
class ParameterInstr : public Definition {
|
class ParameterInstr : public TemplateDefinition<0, NoThrow> {
|
||||||
public:
|
public:
|
||||||
ParameterInstr(intptr_t index,
|
ParameterInstr(intptr_t index,
|
||||||
intptr_t param_offset,
|
intptr_t param_offset,
|
||||||
|
@ -2687,12 +2708,6 @@ class ParameterInstr : public Definition {
|
||||||
virtual BlockEntryInstr* GetBlock() { return block_; }
|
virtual BlockEntryInstr* GetBlock() { return block_; }
|
||||||
void set_block(BlockEntryInstr* block) { block_ = block; }
|
void set_block(BlockEntryInstr* block) { block_ = block; }
|
||||||
|
|
||||||
intptr_t InputCount() const { return 0; }
|
|
||||||
Value* InputAt(intptr_t i) const {
|
|
||||||
UNREACHABLE();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Representation representation() const { return representation_; }
|
virtual Representation representation() const { return representation_; }
|
||||||
|
|
||||||
virtual Representation RequiredInputRepresentation(intptr_t index) const {
|
virtual Representation RequiredInputRepresentation(intptr_t index) const {
|
||||||
|
@ -2711,13 +2726,9 @@ class ParameterInstr : public Definition {
|
||||||
|
|
||||||
virtual CompileType ComputeType() const;
|
virtual CompileType ComputeType() const;
|
||||||
|
|
||||||
virtual bool MayThrow() const { return false; }
|
|
||||||
|
|
||||||
PRINT_OPERANDS_TO_SUPPORT
|
PRINT_OPERANDS_TO_SUPPORT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
|
|
||||||
|
|
||||||
const intptr_t index_;
|
const intptr_t index_;
|
||||||
|
|
||||||
// The offset (in words) of the last slot of the parameter, relative
|
// The offset (in words) of the last slot of the parameter, relative
|
||||||
|
@ -2739,7 +2750,7 @@ class ParameterInstr : public Definition {
|
||||||
// NativeEntryInstr::EmitNativeCode for more details.
|
// NativeEntryInstr::EmitNativeCode for more details.
|
||||||
//
|
//
|
||||||
// TOOD(33549): Unify with ParameterInstr.
|
// TOOD(33549): Unify with ParameterInstr.
|
||||||
class NativeParameterInstr : public Definition {
|
class NativeParameterInstr : public TemplateDefinition<0, NoThrow> {
|
||||||
public:
|
public:
|
||||||
NativeParameterInstr(const compiler::ffi::CallbackMarshaller& marshaller,
|
NativeParameterInstr(const compiler::ffi::CallbackMarshaller& marshaller,
|
||||||
intptr_t def_index)
|
intptr_t def_index)
|
||||||
|
@ -2751,12 +2762,6 @@ class NativeParameterInstr : public Definition {
|
||||||
return marshaller_.RepInFfiCall(def_index_);
|
return marshaller_.RepInFfiCall(def_index_);
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t InputCount() const { return 0; }
|
|
||||||
Value* InputAt(intptr_t i) const {
|
|
||||||
UNREACHABLE();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool ComputeCanDeoptimize() const { return false; }
|
virtual bool ComputeCanDeoptimize() const { return false; }
|
||||||
|
|
||||||
virtual bool HasUnknownSideEffects() const { return false; }
|
virtual bool HasUnknownSideEffects() const { return false; }
|
||||||
|
@ -2764,13 +2769,9 @@ class NativeParameterInstr : public Definition {
|
||||||
// TODO(sjindel): We can make this more precise.
|
// TODO(sjindel): We can make this more precise.
|
||||||
virtual CompileType ComputeType() const { return CompileType::Dynamic(); }
|
virtual CompileType ComputeType() const { return CompileType::Dynamic(); }
|
||||||
|
|
||||||
virtual bool MayThrow() const { return false; }
|
|
||||||
|
|
||||||
PRINT_OPERANDS_TO_SUPPORT
|
PRINT_OPERANDS_TO_SUPPORT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
|
|
||||||
|
|
||||||
const compiler::ffi::CallbackMarshaller& marshaller_;
|
const compiler::ffi::CallbackMarshaller& marshaller_;
|
||||||
const intptr_t def_index_;
|
const intptr_t def_index_;
|
||||||
|
|
||||||
|
@ -4013,23 +4014,19 @@ struct ArgumentsInfo {
|
||||||
};
|
};
|
||||||
|
|
||||||
template <intptr_t kExtraInputs>
|
template <intptr_t kExtraInputs>
|
||||||
class TemplateDartCall : public Definition {
|
class TemplateDartCall : public VariadicDefinition {
|
||||||
public:
|
public:
|
||||||
TemplateDartCall(intptr_t deopt_id,
|
TemplateDartCall(intptr_t deopt_id,
|
||||||
intptr_t type_args_len,
|
intptr_t type_args_len,
|
||||||
const Array& argument_names,
|
const Array& argument_names,
|
||||||
InputsArray* inputs,
|
InputsArray* inputs,
|
||||||
const InstructionSource& source)
|
const InstructionSource& source)
|
||||||
: Definition(source, deopt_id),
|
: VariadicDefinition(inputs, source, deopt_id),
|
||||||
type_args_len_(type_args_len),
|
type_args_len_(type_args_len),
|
||||||
argument_names_(argument_names),
|
argument_names_(argument_names),
|
||||||
inputs_(inputs),
|
|
||||||
token_pos_(source.token_pos) {
|
token_pos_(source.token_pos) {
|
||||||
ASSERT(argument_names.IsZoneHandle() || argument_names.InVMIsolateHeap());
|
ASSERT(argument_names.IsZoneHandle() || argument_names.InVMIsolateHeap());
|
||||||
ASSERT(inputs_->length() >= kExtraInputs);
|
ASSERT(inputs_->length() >= kExtraInputs);
|
||||||
for (intptr_t i = 0, n = inputs_->length(); i < n; ++i) {
|
|
||||||
SetInputAt(i, (*inputs_)[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline StringPtr Selector();
|
inline StringPtr Selector();
|
||||||
|
@ -4037,8 +4034,6 @@ class TemplateDartCall : public Definition {
|
||||||
virtual bool MayThrow() const { return true; }
|
virtual bool MayThrow() const { return true; }
|
||||||
virtual bool CanCallDart() const { return true; }
|
virtual bool CanCallDart() const { return true; }
|
||||||
|
|
||||||
virtual intptr_t InputCount() const { return inputs_->length(); }
|
|
||||||
virtual Value* InputAt(intptr_t i) const { return inputs_->At(i); }
|
|
||||||
virtual bool ComputeCanDeoptimize() const { return false; }
|
virtual bool ComputeCanDeoptimize() const { return false; }
|
||||||
virtual bool ComputeCanDeoptimizeAfterCall() const {
|
virtual bool ComputeCanDeoptimizeAfterCall() const {
|
||||||
return !CompilerState::Current().is_aot();
|
return !CompilerState::Current().is_aot();
|
||||||
|
@ -4095,13 +4090,8 @@ class TemplateDartCall : public Definition {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) {
|
|
||||||
(*inputs_)[i] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
intptr_t type_args_len_;
|
intptr_t type_args_len_;
|
||||||
const Array& argument_names_;
|
const Array& argument_names_;
|
||||||
InputsArray* inputs_;
|
|
||||||
PushArgumentsArray* push_arguments_ = nullptr;
|
PushArgumentsArray* push_arguments_ = nullptr;
|
||||||
TokenPosition token_pos_;
|
TokenPosition token_pos_;
|
||||||
|
|
||||||
|
@ -5063,17 +5053,17 @@ class LoadLocalInstr : public TemplateDefinition<0, NoThrow> {
|
||||||
class DropTempsInstr : public Definition {
|
class DropTempsInstr : public Definition {
|
||||||
public:
|
public:
|
||||||
DropTempsInstr(intptr_t num_temps, Value* value)
|
DropTempsInstr(intptr_t num_temps, Value* value)
|
||||||
: num_temps_(num_temps), value_(NULL) {
|
: num_temps_(num_temps), has_input_(value != nullptr) {
|
||||||
if (value != NULL) {
|
if (has_input_) {
|
||||||
SetInputAt(0, value);
|
SetInputAt(0, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_INSTRUCTION(DropTemps)
|
DECLARE_INSTRUCTION(DropTemps)
|
||||||
|
|
||||||
virtual intptr_t InputCount() const { return value_ != NULL ? 1 : 0; }
|
virtual intptr_t InputCount() const { return has_input_ ? 1 : 0; }
|
||||||
virtual Value* InputAt(intptr_t i) const {
|
virtual Value* InputAt(intptr_t i) const {
|
||||||
ASSERT((value_ != NULL) && (i == 0));
|
ASSERT(has_input_ && (i == 0));
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5097,10 +5087,14 @@ class DropTempsInstr : public Definition {
|
||||||
PRINT_OPERANDS_TO_SUPPORT
|
PRINT_OPERANDS_TO_SUPPORT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) { value_ = value; }
|
virtual void RawSetInputAt(intptr_t i, Value* value) {
|
||||||
|
ASSERT(has_input_);
|
||||||
|
value_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
const intptr_t num_temps_;
|
const intptr_t num_temps_;
|
||||||
Value* value_;
|
const bool has_input_;
|
||||||
|
Value* value_ = nullptr;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(DropTempsInstr);
|
DISALLOW_COPY_AND_ASSIGN(DropTempsInstr);
|
||||||
};
|
};
|
||||||
|
@ -5194,8 +5188,8 @@ class StoreLocalInstr : public TemplateDefinition<1, NoThrow> {
|
||||||
|
|
||||||
class NativeCallInstr : public TemplateDartCall<0> {
|
class NativeCallInstr : public TemplateDartCall<0> {
|
||||||
public:
|
public:
|
||||||
NativeCallInstr(const String* name,
|
NativeCallInstr(const String& name,
|
||||||
const Function* function,
|
const Function& function,
|
||||||
bool link_lazily,
|
bool link_lazily,
|
||||||
const InstructionSource& source,
|
const InstructionSource& source,
|
||||||
InputsArray* args)
|
InputsArray* args)
|
||||||
|
@ -5207,14 +5201,14 @@ class NativeCallInstr : public TemplateDartCall<0> {
|
||||||
is_auto_scope_(true),
|
is_auto_scope_(true),
|
||||||
link_lazily_(link_lazily),
|
link_lazily_(link_lazily),
|
||||||
token_pos_(source.token_pos) {
|
token_pos_(source.token_pos) {
|
||||||
ASSERT(name->IsZoneHandle());
|
ASSERT(name.IsZoneHandle());
|
||||||
ASSERT(function->IsZoneHandle());
|
ASSERT(function.IsZoneHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_INSTRUCTION(NativeCall)
|
DECLARE_INSTRUCTION(NativeCall)
|
||||||
|
|
||||||
const String& native_name() const { return *native_name_; }
|
const String& native_name() const { return native_name_; }
|
||||||
const Function& function() const { return *function_; }
|
const Function& function() const { return function_; }
|
||||||
NativeFunction native_c_function() const { return native_c_function_; }
|
NativeFunction native_c_function() const { return native_c_function_; }
|
||||||
bool is_bootstrap_native() const { return is_bootstrap_native_; }
|
bool is_bootstrap_native() const { return is_bootstrap_native_; }
|
||||||
bool is_auto_scope() const { return is_auto_scope_; }
|
bool is_auto_scope() const { return is_auto_scope_; }
|
||||||
|
@ -5240,8 +5234,8 @@ class NativeCallInstr : public TemplateDartCall<0> {
|
||||||
void set_is_bootstrap_native(bool value) { is_bootstrap_native_ = value; }
|
void set_is_bootstrap_native(bool value) { is_bootstrap_native_ = value; }
|
||||||
void set_is_auto_scope(bool value) { is_auto_scope_ = value; }
|
void set_is_auto_scope(bool value) { is_auto_scope_ = value; }
|
||||||
|
|
||||||
const String* native_name_;
|
const String& native_name_;
|
||||||
const Function* function_;
|
const Function& function_;
|
||||||
NativeFunction native_c_function_;
|
NativeFunction native_c_function_;
|
||||||
bool is_bootstrap_native_;
|
bool is_bootstrap_native_;
|
||||||
bool is_auto_scope_;
|
bool is_auto_scope_;
|
||||||
|
@ -5260,22 +5254,17 @@ class NativeCallInstr : public TemplateDartCall<0> {
|
||||||
// - The arguments to the native call, marshalled in IL as far as possible.
|
// - The arguments to the native call, marshalled in IL as far as possible.
|
||||||
// - The argument address.
|
// - The argument address.
|
||||||
// - A TypedData for the return value to populate in machine code (optional).
|
// - A TypedData for the return value to populate in machine code (optional).
|
||||||
class FfiCallInstr : public Definition {
|
class FfiCallInstr : public VariadicDefinitionWithEmbeddedInputs {
|
||||||
public:
|
public:
|
||||||
FfiCallInstr(Zone* zone,
|
FfiCallInstr(intptr_t deopt_id,
|
||||||
intptr_t deopt_id,
|
|
||||||
const compiler::ffi::CallMarshaller& marshaller,
|
const compiler::ffi::CallMarshaller& marshaller,
|
||||||
bool is_leaf)
|
bool is_leaf)
|
||||||
: Definition(deopt_id),
|
: VariadicDefinitionWithEmbeddedInputs(
|
||||||
zone_(zone),
|
marshaller.NumDefinitions() + 1 +
|
||||||
|
(marshaller.PassTypedData() ? 1 : 0),
|
||||||
|
deopt_id),
|
||||||
marshaller_(marshaller),
|
marshaller_(marshaller),
|
||||||
inputs_(marshaller.NumDefinitions() + 1 +
|
is_leaf_(is_leaf) {}
|
||||||
(marshaller.PassTypedData() ? 1 : 0)),
|
|
||||||
is_leaf_(is_leaf) {
|
|
||||||
inputs_.FillWith(
|
|
||||||
nullptr, 0,
|
|
||||||
marshaller.NumDefinitions() + 1 + (marshaller.PassTypedData() ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLARE_INSTRUCTION(FfiCall)
|
DECLARE_INSTRUCTION(FfiCall)
|
||||||
|
|
||||||
|
@ -5288,8 +5277,6 @@ class FfiCallInstr : public Definition {
|
||||||
return marshaller_.NumDefinitions() + 1;
|
return marshaller_.NumDefinitions() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual intptr_t InputCount() const { return inputs_.length(); }
|
|
||||||
virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
|
|
||||||
virtual bool MayThrow() const {
|
virtual bool MayThrow() const {
|
||||||
// By Dart_PropagateError.
|
// By Dart_PropagateError.
|
||||||
return true;
|
return true;
|
||||||
|
@ -5320,8 +5307,6 @@ class FfiCallInstr : public Definition {
|
||||||
PRINT_OPERANDS_TO_SUPPORT
|
PRINT_OPERANDS_TO_SUPPORT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
|
|
||||||
|
|
||||||
LocationSummary* MakeLocationSummaryInternal(Zone* zone,
|
LocationSummary* MakeLocationSummaryInternal(Zone* zone,
|
||||||
bool is_optimizing,
|
bool is_optimizing,
|
||||||
const RegList temps) const;
|
const RegList temps) const;
|
||||||
|
@ -5338,21 +5323,16 @@ class FfiCallInstr : public Definition {
|
||||||
const Register temp0,
|
const Register temp0,
|
||||||
const Register temp1);
|
const Register temp1);
|
||||||
|
|
||||||
Zone* const zone_;
|
|
||||||
const compiler::ffi::CallMarshaller& marshaller_;
|
const compiler::ffi::CallMarshaller& marshaller_;
|
||||||
|
|
||||||
GrowableArray<Value*> inputs_;
|
|
||||||
|
|
||||||
bool is_leaf_;
|
bool is_leaf_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(FfiCallInstr);
|
DISALLOW_COPY_AND_ASSIGN(FfiCallInstr);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Has the target address in a register passed as the last input in IL.
|
// Has the target address in a register passed as the last input in IL.
|
||||||
class CCallInstr : public Definition {
|
class CCallInstr : public VariadicDefinition {
|
||||||
public:
|
public:
|
||||||
CCallInstr(
|
CCallInstr(
|
||||||
Zone* zone,
|
|
||||||
const compiler::ffi::NativeCallingConvention& native_calling_convention,
|
const compiler::ffi::NativeCallingConvention& native_calling_convention,
|
||||||
InputsArray* inputs);
|
InputsArray* inputs);
|
||||||
|
|
||||||
|
@ -5366,8 +5346,6 @@ class CCallInstr : public Definition {
|
||||||
return native_calling_convention_.argument_locations().length();
|
return native_calling_convention_.argument_locations().length();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual intptr_t InputCount() const { return inputs_->length(); }
|
|
||||||
virtual Value* InputAt(intptr_t i) const { return inputs_->At(i); }
|
|
||||||
virtual bool MayThrow() const { return false; }
|
virtual bool MayThrow() const { return false; }
|
||||||
|
|
||||||
virtual bool ComputeCanDeoptimize() const { return false; }
|
virtual bool ComputeCanDeoptimize() const { return false; }
|
||||||
|
@ -5386,13 +5364,7 @@ class CCallInstr : public Definition {
|
||||||
PRINT_OPERANDS_TO_SUPPORT
|
PRINT_OPERANDS_TO_SUPPORT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) {
|
|
||||||
(*inputs_)[i] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Zone* const zone_;
|
|
||||||
const compiler::ffi::NativeCallingConvention& native_calling_convention_;
|
const compiler::ffi::NativeCallingConvention& native_calling_convention_;
|
||||||
InputsArray* inputs_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(CCallInstr);
|
DISALLOW_COPY_AND_ASSIGN(CCallInstr);
|
||||||
};
|
};
|
||||||
|
@ -6392,11 +6364,12 @@ class AllocateObjectInstr : public AllocationInstr {
|
||||||
Value* type_arguments = nullptr)
|
Value* type_arguments = nullptr)
|
||||||
: AllocationInstr(source, deopt_id),
|
: AllocationInstr(source, deopt_id),
|
||||||
cls_(cls),
|
cls_(cls),
|
||||||
|
has_type_arguments_(type_arguments != nullptr),
|
||||||
type_arguments_(type_arguments) {
|
type_arguments_(type_arguments) {
|
||||||
ASSERT(cls.IsZoneHandle());
|
ASSERT(cls.IsZoneHandle());
|
||||||
ASSERT(!cls.IsNull());
|
ASSERT(!cls.IsNull());
|
||||||
ASSERT((cls.NumTypeArguments() > 0) == (type_arguments != nullptr));
|
ASSERT((cls.NumTypeArguments() > 0) == has_type_arguments_);
|
||||||
if (type_arguments != nullptr) {
|
if (has_type_arguments_) {
|
||||||
SetInputAt(kTypeArgumentsPos, type_arguments);
|
SetInputAt(kTypeArgumentsPos, type_arguments);
|
||||||
type_arguments_slot_ =
|
type_arguments_slot_ =
|
||||||
&Slot::GetTypeArgumentsSlotFor(Thread::Current(), cls);
|
&Slot::GetTypeArgumentsSlotFor(Thread::Current(), cls);
|
||||||
|
@ -6409,11 +6382,9 @@ class AllocateObjectInstr : public AllocationInstr {
|
||||||
const Class& cls() const { return cls_; }
|
const Class& cls() const { return cls_; }
|
||||||
Value* type_arguments() const { return type_arguments_; }
|
Value* type_arguments() const { return type_arguments_; }
|
||||||
|
|
||||||
virtual intptr_t InputCount() const {
|
virtual intptr_t InputCount() const { return has_type_arguments_ ? 1 : 0; }
|
||||||
return (type_arguments_ != nullptr) ? 1 : 0;
|
|
||||||
}
|
|
||||||
virtual Value* InputAt(intptr_t i) const {
|
virtual Value* InputAt(intptr_t i) const {
|
||||||
ASSERT(type_arguments_ != nullptr && i == kTypeArgumentsPos);
|
ASSERT(has_type_arguments_ && i == kTypeArgumentsPos);
|
||||||
return type_arguments_;
|
return type_arguments_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6435,12 +6406,12 @@ class AllocateObjectInstr : public AllocationInstr {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) {
|
virtual void RawSetInputAt(intptr_t i, Value* value) {
|
||||||
ASSERT((type_arguments_ != nullptr) && (i == kTypeArgumentsPos));
|
ASSERT(has_type_arguments_ && (i == kTypeArgumentsPos));
|
||||||
ASSERT(value != nullptr);
|
|
||||||
type_arguments_ = value;
|
type_arguments_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Class& cls_;
|
const Class& cls_;
|
||||||
|
const bool has_type_arguments_;
|
||||||
Value* type_arguments_;
|
Value* type_arguments_;
|
||||||
const Slot* type_arguments_slot_ = nullptr;
|
const Slot* type_arguments_slot_ = nullptr;
|
||||||
|
|
||||||
|
@ -6529,26 +6500,22 @@ class AllocateUninitializedContextInstr : public TemplateAllocation<0> {
|
||||||
// This instruction captures the state of the object which had its allocation
|
// This instruction captures the state of the object which had its allocation
|
||||||
// removed during the AllocationSinking pass.
|
// removed during the AllocationSinking pass.
|
||||||
// It does not produce any real code only deoptimization information.
|
// It does not produce any real code only deoptimization information.
|
||||||
class MaterializeObjectInstr : public Definition {
|
class MaterializeObjectInstr : public VariadicDefinition {
|
||||||
public:
|
public:
|
||||||
MaterializeObjectInstr(AllocationInstr* allocation,
|
MaterializeObjectInstr(AllocationInstr* allocation,
|
||||||
const Class& cls,
|
const Class& cls,
|
||||||
intptr_t num_elements,
|
intptr_t num_elements,
|
||||||
const ZoneGrowableArray<const Slot*>& slots,
|
const ZoneGrowableArray<const Slot*>& slots,
|
||||||
ZoneGrowableArray<Value*>* values)
|
ZoneGrowableArray<Value*>* values)
|
||||||
: allocation_(allocation),
|
: VariadicDefinition(values),
|
||||||
|
allocation_(allocation),
|
||||||
cls_(cls),
|
cls_(cls),
|
||||||
num_elements_(num_elements),
|
num_elements_(num_elements),
|
||||||
slots_(slots),
|
slots_(slots),
|
||||||
values_(values),
|
|
||||||
locations_(nullptr),
|
locations_(nullptr),
|
||||||
visited_for_liveness_(false),
|
visited_for_liveness_(false),
|
||||||
registers_remapped_(false) {
|
registers_remapped_(false) {
|
||||||
ASSERT(slots_.length() == values_->length());
|
ASSERT(slots_.length() == values->length());
|
||||||
for (intptr_t i = 0; i < InputCount(); i++) {
|
|
||||||
InputAt(i)->set_instruction(this);
|
|
||||||
InputAt(i)->set_use_index(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocationInstr* allocation() const { return allocation_; }
|
AllocationInstr* allocation() const { return allocation_; }
|
||||||
|
@ -6564,10 +6531,6 @@ class MaterializeObjectInstr : public Definition {
|
||||||
|
|
||||||
DECLARE_INSTRUCTION(MaterializeObject)
|
DECLARE_INSTRUCTION(MaterializeObject)
|
||||||
|
|
||||||
virtual intptr_t InputCount() const { return values_->length(); }
|
|
||||||
|
|
||||||
virtual Value* InputAt(intptr_t i) const { return (*values_)[i]; }
|
|
||||||
|
|
||||||
// SelectRepresentations pass is run once more while MaterializeObject
|
// SelectRepresentations pass is run once more while MaterializeObject
|
||||||
// instructions are still in the graph. To avoid any redundant boxing
|
// instructions are still in the graph. To avoid any redundant boxing
|
||||||
// operations inserted by that pass we should indicate that this
|
// operations inserted by that pass we should indicate that this
|
||||||
|
@ -6594,15 +6557,10 @@ class MaterializeObjectInstr : public Definition {
|
||||||
PRINT_OPERANDS_TO_SUPPORT
|
PRINT_OPERANDS_TO_SUPPORT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) {
|
|
||||||
(*values_)[i] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
AllocationInstr* allocation_;
|
AllocationInstr* allocation_;
|
||||||
const Class& cls_;
|
const Class& cls_;
|
||||||
intptr_t num_elements_;
|
intptr_t num_elements_;
|
||||||
const ZoneGrowableArray<const Slot*>& slots_;
|
const ZoneGrowableArray<const Slot*>& slots_;
|
||||||
ZoneGrowableArray<Value*>* values_;
|
|
||||||
Location* locations_;
|
Location* locations_;
|
||||||
|
|
||||||
bool visited_for_liveness_;
|
bool visited_for_liveness_;
|
||||||
|
@ -8692,7 +8650,7 @@ class FloatToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(sjindel): Replace with FFICallInstr.
|
// TODO(sjindel): Replace with FFICallInstr.
|
||||||
class InvokeMathCFunctionInstr : public PureDefinition {
|
class InvokeMathCFunctionInstr : public VariadicDefinition {
|
||||||
public:
|
public:
|
||||||
InvokeMathCFunctionInstr(ZoneGrowableArray<Value*>* inputs,
|
InvokeMathCFunctionInstr(ZoneGrowableArray<Value*>* inputs,
|
||||||
intptr_t deopt_id,
|
intptr_t deopt_id,
|
||||||
|
@ -8726,9 +8684,8 @@ class InvokeMathCFunctionInstr : public PureDefinition {
|
||||||
|
|
||||||
virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }
|
virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }
|
||||||
|
|
||||||
virtual intptr_t InputCount() const { return inputs_->length(); }
|
virtual bool AllowsCSE() const { return true; }
|
||||||
|
virtual bool HasUnknownSideEffects() const { return false; }
|
||||||
virtual Value* InputAt(intptr_t i) const { return (*inputs_)[i]; }
|
|
||||||
|
|
||||||
virtual bool AttributesEqual(const Instruction& other) const {
|
virtual bool AttributesEqual(const Instruction& other) const {
|
||||||
auto const other_invoke = other.AsInvokeMathCFunction();
|
auto const other_invoke = other.AsInvokeMathCFunction();
|
||||||
|
@ -8744,11 +8701,6 @@ class InvokeMathCFunctionInstr : public PureDefinition {
|
||||||
PRINT_OPERANDS_TO_SUPPORT
|
PRINT_OPERANDS_TO_SUPPORT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void RawSetInputAt(intptr_t i, Value* value) {
|
|
||||||
(*inputs_)[i] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZoneGrowableArray<Value*>* inputs_;
|
|
||||||
const MethodRecognizer::Kind recognized_kind_;
|
const MethodRecognizer::Kind recognized_kind_;
|
||||||
const TokenPosition token_pos_;
|
const TokenPosition token_pos_;
|
||||||
|
|
||||||
|
@ -9853,7 +9805,7 @@ class Environment : public ZoneAllocated {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Function& function() const { return parsed_function_.function(); }
|
const Function& function() const { return function_; }
|
||||||
|
|
||||||
Environment* DeepCopy(Zone* zone) const { return DeepCopy(zone, Length()); }
|
Environment* DeepCopy(Zone* zone) const { return DeepCopy(zone, Length()); }
|
||||||
|
|
||||||
|
@ -9893,14 +9845,14 @@ class Environment : public ZoneAllocated {
|
||||||
Environment(intptr_t length,
|
Environment(intptr_t length,
|
||||||
intptr_t fixed_parameter_count,
|
intptr_t fixed_parameter_count,
|
||||||
intptr_t lazy_deopt_pruning_count,
|
intptr_t lazy_deopt_pruning_count,
|
||||||
const ParsedFunction& parsed_function,
|
const Function& function,
|
||||||
Environment* outer)
|
Environment* outer)
|
||||||
: values_(length),
|
: values_(length),
|
||||||
fixed_parameter_count_(fixed_parameter_count),
|
fixed_parameter_count_(fixed_parameter_count),
|
||||||
bitfield_(DeoptIdBits::encode(DeoptId::kNone) |
|
bitfield_(DeoptIdBits::encode(DeoptId::kNone) |
|
||||||
LazyDeoptToBeforeDeoptId::encode(false) |
|
LazyDeoptToBeforeDeoptId::encode(false) |
|
||||||
LazyDeoptPruningBits::encode(lazy_deopt_pruning_count)),
|
LazyDeoptPruningBits::encode(lazy_deopt_pruning_count)),
|
||||||
parsed_function_(parsed_function),
|
function_(function),
|
||||||
outer_(outer) {}
|
outer_(outer) {}
|
||||||
|
|
||||||
void SetDeoptId(intptr_t deopt_id) {
|
void SetDeoptId(intptr_t deopt_id) {
|
||||||
|
@ -9919,7 +9871,7 @@ class Environment : public ZoneAllocated {
|
||||||
// Deoptimization id associated with this environment. Only set for
|
// Deoptimization id associated with this environment. Only set for
|
||||||
// outer environments.
|
// outer environments.
|
||||||
uintptr_t bitfield_;
|
uintptr_t bitfield_;
|
||||||
const ParsedFunction& parsed_function_;
|
const Function& function_;
|
||||||
Environment* outer_;
|
Environment* outer_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Environment);
|
DISALLOW_COPY_AND_ASSIGN(Environment);
|
||||||
|
|
|
@ -961,7 +961,7 @@ FlowGraph* SetupFfiFlowgraph(TestPipeline* pipeline,
|
||||||
FlowGraph* flow_graph = pipeline->RunPasses({CompilerPass::kComputeSSA});
|
FlowGraph* flow_graph = pipeline->RunPasses({CompilerPass::kComputeSSA});
|
||||||
|
|
||||||
// Make an FfiCall based on ffi_trampoline that calls our native function.
|
// Make an FfiCall based on ffi_trampoline that calls our native function.
|
||||||
auto ffi_call = new FfiCallInstr(zone, DeoptId::kNone, marshaller, is_leaf);
|
auto ffi_call = new FfiCallInstr(DeoptId::kNone, marshaller, is_leaf);
|
||||||
RELEASE_ASSERT(ffi_call->InputCount() == 1);
|
RELEASE_ASSERT(ffi_call->InputCount() == 1);
|
||||||
// TargetAddress is the function pointer called.
|
// TargetAddress is the function pointer called.
|
||||||
const Representation address_repr =
|
const Representation address_repr =
|
||||||
|
|
|
@ -394,9 +394,8 @@ Fragment FlowGraphBuilder::FfiCall(
|
||||||
const compiler::ffi::CallMarshaller& marshaller) {
|
const compiler::ffi::CallMarshaller& marshaller) {
|
||||||
Fragment body;
|
Fragment body;
|
||||||
|
|
||||||
FfiCallInstr* const call =
|
FfiCallInstr* const call = new (Z) FfiCallInstr(
|
||||||
new (Z) FfiCallInstr(Z, GetNextDeoptId(), marshaller,
|
GetNextDeoptId(), marshaller, parsed_function_->function().FfiIsLeaf());
|
||||||
parsed_function_->function().FfiIsLeaf());
|
|
||||||
|
|
||||||
for (intptr_t i = call->InputCount() - 1; i >= 0; --i) {
|
for (intptr_t i = call->InputCount() - 1; i >= 0; --i) {
|
||||||
call->SetInputAt(i, Pop());
|
call->SetInputAt(i, Pop());
|
||||||
|
@ -419,8 +418,7 @@ Fragment FlowGraphBuilder::CCall(
|
||||||
for (intptr_t i = num_arguments - 1; i >= 0; --i) {
|
for (intptr_t i = num_arguments - 1; i >= 0; --i) {
|
||||||
(*arguments)[i] = Pop();
|
(*arguments)[i] = Pop();
|
||||||
}
|
}
|
||||||
auto* const call =
|
auto* const call = new (Z) CCallInstr(native_calling_convention, arguments);
|
||||||
new (Z) CCallInstr(Z, native_calling_convention, arguments);
|
|
||||||
|
|
||||||
Push(call);
|
Push(call);
|
||||||
body <<= call;
|
body <<= call;
|
||||||
|
@ -559,15 +557,15 @@ Fragment FlowGraphBuilder::StoreLateField(const Field& field,
|
||||||
return instructions;
|
return instructions;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fragment FlowGraphBuilder::NativeCall(const String* name,
|
Fragment FlowGraphBuilder::NativeCall(const String& name,
|
||||||
const Function* function) {
|
const Function& function) {
|
||||||
InlineBailout("kernel::FlowGraphBuilder::NativeCall");
|
InlineBailout("kernel::FlowGraphBuilder::NativeCall");
|
||||||
const intptr_t num_args =
|
const intptr_t num_args =
|
||||||
function->NumParameters() + (function->IsGeneric() ? 1 : 0);
|
function.NumParameters() + (function.IsGeneric() ? 1 : 0);
|
||||||
InputsArray* arguments = GetArguments(num_args);
|
InputsArray* arguments = GetArguments(num_args);
|
||||||
NativeCallInstr* call = new (Z)
|
NativeCallInstr* call = new (Z)
|
||||||
NativeCallInstr(name, function, FLAG_link_natives_lazily,
|
NativeCallInstr(name, function, FLAG_link_natives_lazily,
|
||||||
InstructionSource(function->end_token_pos()), arguments);
|
InstructionSource(function.end_token_pos()), arguments);
|
||||||
Push(call);
|
Push(call);
|
||||||
return Fragment(call);
|
return Fragment(call);
|
||||||
}
|
}
|
||||||
|
@ -838,7 +836,7 @@ Fragment FlowGraphBuilder::NativeFunctionBody(const Function& function,
|
||||||
for (intptr_t i = 0; i < function.NumParameters(); ++i) {
|
for (intptr_t i = 0; i < function.NumParameters(); ++i) {
|
||||||
body += LoadLocal(parsed_function_->RawParameterVariable(i));
|
body += LoadLocal(parsed_function_->RawParameterVariable(i));
|
||||||
}
|
}
|
||||||
body += NativeCall(&name, &function);
|
body += NativeCall(name, function);
|
||||||
// We typecheck results of native calls for type safety.
|
// We typecheck results of native calls for type safety.
|
||||||
body +=
|
body +=
|
||||||
Return(TokenPosition::kNoSource, /* omit_result_type_check = */ false);
|
Return(TokenPosition::kNoSource, /* omit_result_type_check = */ false);
|
||||||
|
|
|
@ -197,7 +197,7 @@ class FlowGraphBuilder : public BaseFlowGraphBuilder {
|
||||||
Fragment StoreLateField(const Field& field,
|
Fragment StoreLateField(const Field& field,
|
||||||
LocalVariable* instance,
|
LocalVariable* instance,
|
||||||
LocalVariable* setter_value);
|
LocalVariable* setter_value);
|
||||||
Fragment NativeCall(const String* name, const Function* function);
|
Fragment NativeCall(const String& name, const Function& function);
|
||||||
Fragment Return(
|
Fragment Return(
|
||||||
TokenPosition position,
|
TokenPosition position,
|
||||||
bool omit_result_type_check = false,
|
bool omit_result_type_check = false,
|
||||||
|
|
Loading…
Reference in a new issue