Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Unified Diff: runtime/vm/aot_optimizer.cc

Issue 2805903004: Working implementation of #29153 range check in as-casts. (Closed)
Patch Set: Incorporate @rmacnak's feedback: ZoneHandle, position, symbol null. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/lib/errors_patch.dart ('k') | runtime/vm/method_recognizer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
« no previous file with comments | « runtime/lib/errors_patch.dart ('k') | runtime/vm/method_recognizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698