| Index: runtime/vm/flow_graph_type_propagator.cc
|
| diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
|
| index 8b8e9618a3a43af14d77388ea858df2630a7d99c..aa5dd158d7d116052447cc1c2caeac9a4867d4f3 100644
|
| --- a/runtime/vm/flow_graph_type_propagator.cc
|
| +++ b/runtime/vm/flow_graph_type_propagator.cc
|
| @@ -21,6 +21,24 @@ DEFINE_FLAG(bool,
|
|
|
| DECLARE_FLAG(bool, propagate_types);
|
|
|
| +static void TraceStrongModeType(const Instruction* instr,
|
| + const AbstractType& type) {
|
| + if (FLAG_trace_experimental_strong_mode) {
|
| + THR_Print("[Strong mode] Type of %s - %s\n", instr->ToCString(),
|
| + type.ToCString());
|
| + }
|
| +}
|
| +
|
| +static void TraceStrongModeType(const Instruction* instr,
|
| + CompileType* compileType) {
|
| + if (FLAG_trace_experimental_strong_mode) {
|
| + const AbstractType* type = compileType->ToAbstractType();
|
| + if ((type != NULL) && !type->IsDynamicType()) {
|
| + TraceStrongModeType(instr, *type);
|
| + }
|
| + }
|
| +}
|
| +
|
| void FlowGraphTypePropagator::Propagate(FlowGraph* flow_graph) {
|
| #ifndef PRODUCT
|
| Thread* thread = flow_graph->thread();
|
| @@ -828,6 +846,13 @@ CompileType ParameterInstr::ComputeType() const {
|
| return CompileType(CompileType::kNonNullable, cid, &type);
|
| }
|
|
|
| + if (FLAG_experimental_strong_mode && block_->IsGraphEntry()) {
|
| + LocalScope* scope = graph_entry->parsed_function().node_sequence()->scope();
|
| + const AbstractType& param_type = scope->VariableAt(index())->type();
|
| + TraceStrongModeType(this, param_type);
|
| + return CompileType::FromAbstractType(param_type);
|
| + }
|
| +
|
| return CompileType::Dynamic();
|
| }
|
|
|
| @@ -928,12 +953,36 @@ CompileType AllocateUninitializedContextInstr::ComputeType() const {
|
| &Object::dynamic_type());
|
| }
|
|
|
| +CompileType InstanceCallInstr::ComputeType() const {
|
| + if (FLAG_experimental_strong_mode) {
|
| + const Function& target = interface_target();
|
| + if (!target.IsNull()) {
|
| + // TODO(alexmarkov): instantiate generic result_type
|
| + const AbstractType& result_type =
|
| + AbstractType::ZoneHandle(target.result_type());
|
| + TraceStrongModeType(this, result_type);
|
| + return CompileType::FromAbstractType(result_type);
|
| + }
|
| + }
|
| +
|
| + return CompileType::Dynamic();
|
| +}
|
| +
|
| CompileType PolymorphicInstanceCallInstr::ComputeType() const {
|
| - if (!IsSureToCallSingleRecognizedTarget()) return CompileType::Dynamic();
|
| - const Function& target = *targets_.TargetAt(0)->target;
|
| - return (target.recognized_kind() != MethodRecognizer::kUnknown)
|
| - ? CompileType::FromCid(MethodRecognizer::ResultCid(target))
|
| - : CompileType::Dynamic();
|
| + if (IsSureToCallSingleRecognizedTarget()) {
|
| + const Function& target = *targets_.TargetAt(0)->target;
|
| + if (target.recognized_kind() != MethodRecognizer::kUnknown) {
|
| + return CompileType::FromCid(MethodRecognizer::ResultCid(target));
|
| + }
|
| + }
|
| +
|
| + if (FLAG_experimental_strong_mode) {
|
| + CompileType* type = instance_call()->Type();
|
| + TraceStrongModeType(this, type);
|
| + return *type;
|
| + }
|
| +
|
| + return CompileType::Dynamic();
|
| }
|
|
|
| CompileType StaticCallInstr::ComputeType() const {
|
| @@ -941,20 +990,25 @@ CompileType StaticCallInstr::ComputeType() const {
|
| return CompileType::FromCid(result_cid_);
|
| }
|
|
|
| - if (Isolate::Current()->type_checks()) {
|
| + if (function_.recognized_kind() != MethodRecognizer::kUnknown) {
|
| + return CompileType::FromCid(MethodRecognizer::ResultCid(function_));
|
| + }
|
| +
|
| + if (FLAG_experimental_strong_mode || Isolate::Current()->type_checks()) {
|
| const AbstractType& result_type =
|
| AbstractType::ZoneHandle(function().result_type());
|
| + TraceStrongModeType(this, result_type);
|
| return CompileType::FromAbstractType(result_type);
|
| }
|
|
|
| - return (function_.recognized_kind() != MethodRecognizer::kUnknown)
|
| - ? CompileType::FromCid(MethodRecognizer::ResultCid(function_))
|
| - : CompileType::Dynamic();
|
| + return CompileType::Dynamic();
|
| }
|
|
|
| CompileType LoadLocalInstr::ComputeType() const {
|
| - if (Isolate::Current()->type_checks()) {
|
| - return CompileType::FromAbstractType(local().type());
|
| + if (FLAG_experimental_strong_mode || Isolate::Current()->type_checks()) {
|
| + const AbstractType& local_type = local().type();
|
| + TraceStrongModeType(this, local_type);
|
| + return CompileType::FromAbstractType(local_type);
|
| }
|
| return CompileType::Dynamic();
|
| }
|
| @@ -986,9 +1040,10 @@ CompileType LoadStaticFieldInstr::ComputeType() const {
|
| intptr_t cid = kDynamicCid;
|
| AbstractType* abstract_type = NULL;
|
| const Field& field = this->StaticField();
|
| - if (Isolate::Current()->type_checks()) {
|
| + if (FLAG_experimental_strong_mode || Isolate::Current()->type_checks()) {
|
| cid = kIllegalCid;
|
| abstract_type = &AbstractType::ZoneHandle(field.type());
|
| + TraceStrongModeType(this, *abstract_type);
|
| }
|
| ASSERT(field.is_static());
|
| if (field.is_final()) {
|
| @@ -1039,9 +1094,11 @@ CompileType LoadFieldInstr::ComputeType() const {
|
| }
|
|
|
| const AbstractType* abstract_type = NULL;
|
| - if (Isolate::Current()->type_checks() &&
|
| - (type().IsFunctionType() || type().HasResolvedTypeClass())) {
|
| + if (FLAG_experimental_strong_mode ||
|
| + (Isolate::Current()->type_checks() &&
|
| + (type().IsFunctionType() || type().HasResolvedTypeClass()))) {
|
| abstract_type = &type();
|
| + TraceStrongModeType(this, *abstract_type);
|
| }
|
|
|
| if ((field_ != NULL) && (field_->guarded_cid() != kIllegalCid)) {
|
| @@ -1106,6 +1163,24 @@ CompileType UnaryInt64OpInstr::ComputeType() const {
|
| return CompileType::Int();
|
| }
|
|
|
| +CompileType CheckedSmiOpInstr::ComputeType() const {
|
| + if (FLAG_experimental_strong_mode) {
|
| + CompileType* type = call()->Type();
|
| + TraceStrongModeType(this, type);
|
| + return *type;
|
| + }
|
| + return CompileType::Dynamic();
|
| +}
|
| +
|
| +CompileType CheckedSmiComparisonInstr::ComputeType() const {
|
| + if (FLAG_experimental_strong_mode) {
|
| + CompileType* type = call()->Type();
|
| + TraceStrongModeType(this, type);
|
| + return *type;
|
| + }
|
| + return CompileType::Dynamic();
|
| +}
|
| +
|
| CompileType BoxIntegerInstr::ComputeType() const {
|
| return ValueFitsSmi() ? CompileType::FromCid(kSmiCid) : CompileType::Int();
|
| }
|
|
|