Chromium Code Reviews| Index: runtime/vm/aot_optimizer.cc |
| diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc |
| index 5dfe8f507c5c258647c1c4d08ef7533b7a01ab75..af4deeb6fc4fd82e7a9f4fc77189271e30970fcd 100644 |
| --- a/runtime/vm/aot_optimizer.cc |
| +++ b/runtime/vm/aot_optimizer.cc |
| @@ -1565,6 +1565,122 @@ void AotOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
| const AbstractType& type = |
| AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()); |
| ASSERT(!type.IsMalformedOrMalbounded()); |
| + |
| + if (TypeCheckAsClassEquality(type)) { |
| + LoadClassIdInstr* left_cid = new (Z) LoadClassIdInstr(new (Z) Value(left)); |
| + InsertBefore(call, left_cid, NULL, FlowGraph::kValue); |
| + const intptr_t type_cid = Class::ZoneHandle(Z, type.type_class()).id(); |
| + ConstantInstr* cid = |
| + flow_graph()->GetConstant(Smi::ZoneHandle(Z, Smi::New(type_cid))); |
| + ConstantInstr* pos = flow_graph()->GetConstant( |
| + Smi::ZoneHandle(Z, Smi::New(call->token_pos().Pos()))); |
| + |
| + ZoneGrowableArray<PushArgumentInstr*>* args = |
| + new (Z) ZoneGrowableArray<PushArgumentInstr*>(5); |
| + PushArgumentInstr* arg = new (Z) PushArgumentInstr(new (Z) Value(pos)); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + arg = new (Z) PushArgumentInstr(new (Z) Value(left)); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + arg = new (Z) |
| + PushArgumentInstr(new (Z) Value(flow_graph()->GetConstant(type))); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + arg = new (Z) PushArgumentInstr(new (Z) Value(left_cid)); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + arg = new (Z) PushArgumentInstr(new (Z) Value(cid)); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + |
| + const Library& dart_internal = Library::Handle(Z, Library::CoreLibrary()); |
| + const String& target_name = Symbols::_classIdEqualsAssert(); |
| + const Function& target = Function::ZoneHandle( |
| + Z, dart_internal.LookupFunctionAllowPrivate(target_name)); |
| + ASSERT(!target.IsNull()); |
| + ASSERT(target.IsRecognized()); |
| + ASSERT(target.always_inline()); |
| + |
| + StaticCallInstr* new_call = |
| + new (Z) StaticCallInstr(call->token_pos(), target, |
| + Object::null_array(), // argument_names |
| + args, call->deopt_id()); |
| + Environment* copy = |
| + call->env()->DeepCopy(Z, call->env()->Length() - call->ArgumentCount()); |
| + for (intptr_t i = 0; i < args->length(); ++i) { |
| + copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); |
| + } |
| + call->RemoveEnvironment(); |
| + ReplaceCall(call, new_call); |
| + copy->DeepCopyTo(Z, new_call); |
|
siva
2017/04/13 17:01:04
Maybe not for this CL but in a follow up CL, this
|
| + return; |
| + } |
| + |
| + if (precompiler_ != NULL) { |
| + TypeRangeCache* cache = precompiler_->type_range_cache(); |
| + intptr_t lower_limit, upper_limit; |
| + if (cache != NULL && |
| + cache->InstanceOfHasClassRange(type, &lower_limit, &upper_limit)) { |
| + // left.instanceof(type) => |
| + // _classRangeCheck(left.cid, lower_limit, upper_limit) |
| + |
| + LoadClassIdInstr* left_cid = |
| + new (Z) LoadClassIdInstr(new (Z) Value(left)); |
| + InsertBefore(call, left_cid, NULL, FlowGraph::kValue); |
| + ConstantInstr* lower_cid = |
| + flow_graph()->GetConstant(Smi::ZoneHandle(Z, Smi::New(lower_limit))); |
| + ConstantInstr* upper_cid = |
| + flow_graph()->GetConstant(Smi::ZoneHandle(Z, Smi::New(upper_limit))); |
| + ConstantInstr* pos = flow_graph()->GetConstant( |
| + Smi::ZoneHandle(Z, Smi::New(call->token_pos().Pos()))); |
| + |
| + ZoneGrowableArray<PushArgumentInstr*>* args = |
| + new (Z) ZoneGrowableArray<PushArgumentInstr*>(6); |
| + PushArgumentInstr* arg = new (Z) PushArgumentInstr(new (Z) Value(pos)); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + arg = new (Z) PushArgumentInstr(new (Z) Value(left)); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + arg = new (Z) |
| + PushArgumentInstr(new (Z) Value(flow_graph()->GetConstant(type))); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + arg = new (Z) PushArgumentInstr(new (Z) Value(left_cid)); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + arg = new (Z) PushArgumentInstr(new (Z) Value(lower_cid)); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + arg = new (Z) PushArgumentInstr(new (Z) Value(upper_cid)); |
| + InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| + args->Add(arg); |
| + |
| + const Library& dart_internal = Library::Handle(Z, Library::CoreLibrary()); |
| + const String& target_name = Symbols::_classRangeAssert(); |
| + const Function& target = Function::ZoneHandle( |
| + Z, dart_internal.LookupFunctionAllowPrivate(target_name)); |
| + ASSERT(!target.IsNull()); |
| + ASSERT(target.IsRecognized()); |
| + ASSERT(target.always_inline()); |
| + |
| + StaticCallInstr* new_call = |
| + new (Z) StaticCallInstr(call->token_pos(), target, |
| + Object::null_array(), // argument_names |
| + args, call->deopt_id()); |
| + Environment* copy = call->env()->DeepCopy( |
| + Z, call->env()->Length() - call->ArgumentCount()); |
| + for (intptr_t i = 0; i < args->length(); ++i) { |
| + copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); |
| + } |
| + call->RemoveEnvironment(); |
| + ReplaceCall(call, new_call); |
| + copy->DeepCopyTo(Z, new_call); |
| + return; |
| + } |
| + } |
| + |
| const ICData& unary_checks = |
| ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); |
| const intptr_t number_of_checks = unary_checks.NumberOfChecks(); |