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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 11746024: Optimize instanceof: if all results are true and tests can be done using class only replace instanc… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 12 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/vm/flow_graph_optimizer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_optimizer.cc
===================================================================
--- runtime/vm/flow_graph_optimizer.cc (revision 16610)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -1249,6 +1249,37 @@
}
+// Returns a Boolean constant if all classes in ic_data yield the same type-test
+// result and the type tests do not depend on type arguments. Otherwise return
+// Bool::null().
+RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data,
+ const AbstractType& type) const {
+ ASSERT(ic_data.num_args_tested() == 1); // Unary checks only.
+ if (!type.IsInstantiated()) return Bool::null();
regis 2013/01/03 23:35:26 I suppose there is no need to check that !type.IsM
srdjan 2013/01/04 00:10:55 Added it, just in case.
+ const Class& type_class = Class::Handle(type.type_class());
+ if (type_class.HasTypeArguments()) return Bool::null();
+ const ClassTable& class_table = *Isolate::Current()->class_table();
+ Bool& prev = Bool::Handle();
+ Class& cls = Class::Handle();
+ for (int i = 0; i < ic_data.NumberOfChecks(); i++) {
+ cls = class_table.At(ic_data.GetReceiverClassIdAt(i));
+ if (cls.HasTypeArguments()) return Bool::null();
+ const bool is_subtype = cls.IsNullClass() ?
+ false :
regis 2013/01/03 23:35:26 I do not think this is correct, because null is an
srdjan 2013/01/04 00:10:55 Fixed.
+ cls.IsSubtypeOf(TypeArguments::Handle(),
+ type_class,
+ TypeArguments::Handle(),
+ NULL);
+ if (prev.IsNull()) {
+ prev = is_subtype ? Bool::True() : Bool::False();
+ } else {
+ if (is_subtype != prev.value()) return Bool::null();
+ }
+ }
+ return prev.raw();
+}
+
+
// TODO(srdjan): Use ICData to check if always true or false.
void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
ASSERT(Token::IsTypeTestOperator(call->token_kind()));
@@ -1259,6 +1290,21 @@
AbstractType::Cast(call->ArgumentAt(3)->value()->BoundConstant());
const Bool& negate =
Bool::Cast(call->ArgumentAt(4)->value()->BoundConstant());
+ const ICData& unary_checks =
+ ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks());
+ if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
+ Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type));
+ if (!as_bool.IsNull()) {
+ AddCheckClass(call, left_val->Copy());
+ if (negate.value()) {
+ as_bool = as_bool.value() ? Bool::False() : Bool::True();
+ }
+ ConstantInstr* bool_const = new ConstantInstr(as_bool);
+ call->ReplaceWith(bool_const, current_iterator());
+ RemovePushArguments(call);
+ return;
+ }
+ }
InstanceOfInstr* instance_of =
new InstanceOfInstr(call->token_pos(),
left_val,
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698