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

Unified Diff: runtime/vm/code_generator.cc

Issue 10010029: When checking against non-parametrized types use a cache to hold result tuples (class, result). Tha… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
Index: runtime/vm/code_generator.cc
===================================================================
--- runtime/vm/code_generator.cc (revision 6245)
+++ runtime/vm/code_generator.cc (working copy)
@@ -306,18 +306,20 @@
// Check that the given instance is an instance of the given type.
// Tested instance may not be null, because the null test is inlined.
// Arg0: index of the token of the instanceof test (source location).
-// Arg1: instance being checked.
-// Arg2: type.
-// Arg3: type arguments of the instantiator of the type.
+// Arg1: node id of the instanceof node.
+// Arg2: instance being checked.
+// Arg3: type.
+// Arg4: type arguments of the instantiator of the type.
// Return value: true or false, or may throw a type error in checked mode.
-DEFINE_RUNTIME_ENTRY(Instanceof, 4) {
+DEFINE_RUNTIME_ENTRY(Instanceof, 5) {
ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count());
// TODO(regis): Get the token index from the PcDesc (via DartFrame).
intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
- const Instance& instance = Instance::CheckedHandle(arguments.At(1));
- const AbstractType& type = AbstractType::CheckedHandle(arguments.At(2));
+ intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value();
+ const Instance& instance = Instance::CheckedHandle(arguments.At(2));
+ const AbstractType& type = AbstractType::CheckedHandle(arguments.At(3));
const AbstractTypeArguments& type_instantiator =
- AbstractTypeArguments::CheckedHandle(arguments.At(3));
+ AbstractTypeArguments::CheckedHandle(arguments.At(4));
ASSERT(type.IsFinalized());
Error& malformed_error = Error::Handle();
const Bool& result = Bool::Handle(
@@ -358,6 +360,40 @@
location, no_name, no_name, no_name, malformed_error_message);
UNREACHABLE();
}
+ // Update cache: add class of instance and result.
+ if (type.IsInstantiated() &&
+ !Class::Handle(type.type_class()).HasTypeArguments()) {
+ DartFrameIterator iterator;
+ DartFrame* caller_frame = iterator.NextFrame();
+ ASSERT(caller_frame != NULL);
+ const Code& code = Code::Handle(caller_frame->LookupDartCode());
+ ASSERT(!code.IsNull());
+ uword loc = code.GetTypeTestAtNodeId(node_id);
+ // TODO(srdjan): Check when 'loc' can be 0, once implemented everywhere.
+ if (loc != 0) {
+ // Found type test cache.
+ Array& value = Array::Handle(CodePatcher::GetTypeTestArray(loc));
+ const Class& instance_class = Class::Handle(instance.clazz());
+
+#if defined(DEBUG)
+ // Check for duplicate entries.
+ Class& last_checked = Class::Handle();
+ for (intptr_t i = 0; i < value.Length(); i += 2) {
+ last_checked ^= value.At(i);
+ ASSERT(last_checked.raw() != instance_class.raw());
+ }
+ // Array must be null terminated.
+ ASSERT(last_checked.IsNull());
+#endif
+
+ ASSERT(!value.IsNull());
+ intptr_t old_len = value.Length();
+ value = value.Grow(value, old_len + 2);
+ value.SetAt(old_len - 2, instance_class);
+ value.SetAt(old_len - 1, result);
+ CodePatcher::SetTypeTestArray(loc, value);
+ }
+ }
arguments.SetReturn(result);
}

Powered by Google App Engine
This is Rietveld 408576698