Index: runtime/vm/code_generator.cc |
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc |
index d7c92d7feda298ad796111523904d79065fc929e..d0cdd74ee6410e7b0b1335c0d9f07793ca6d703f 100644 |
--- a/runtime/vm/code_generator.cc |
+++ b/runtime/vm/code_generator.cc |
@@ -204,7 +204,7 @@ DEFINE_RUNTIME_ENTRY(InstantiateType, 2) { |
ASSERT(!type.IsNull() && !type.IsInstantiated()); |
ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); |
Error& bound_error = Error::Handle(); |
- type = type.InstantiateFrom(instantiator, &bound_error); |
+ type = type.InstantiateFrom(instantiator, &bound_error, NULL, Heap::kOld); |
if (!bound_error.IsNull()) { |
// Throw a dynamic type error. |
const intptr_t location = GetCallerLocation(); |
@@ -300,7 +300,7 @@ static void PrintTypeCheck( |
StackFrame* caller_frame = iterator.NextFrame(); |
ASSERT(caller_frame != NULL); |
- const Type& instance_type = Type::Handle(instance.GetType()); |
+ const AbstractType& instance_type = AbstractType::Handle(instance.GetType()); |
ASSERT(instance_type.IsInstantiated()); |
if (type.IsInstantiated()) { |
OS::PrintErr("%s: '%s' %" Pd " %s '%s' %" Pd " (pc: %#" Px ").\n", |
@@ -334,10 +334,10 @@ static void PrintTypeCheck( |
// This updates the type test cache, an array containing 4-value elements |
-// (instance class, instance type arguments, instantiator type arguments and |
-// test_result). It can be applied to classes with type arguments in which |
-// case it contains just the result of the class subtype test, not including |
-// the evaluation of type arguments. |
+// (instance class (or function if the instance is a closure), instance type |
+// arguments, instantiator type arguments and test_result). It can be applied to |
+// classes with type arguments in which case it contains just the result of the |
+// class subtype test, not including the evaluation of type arguments. |
// This operation is currently very slow (lookup of code is not efficient yet). |
static void UpdateTypeTestCache( |
const Instance& instance, |
@@ -360,11 +360,16 @@ static void UpdateTypeTestCache( |
} |
return; |
} |
- TypeArguments& instance_type_arguments = |
- TypeArguments::Handle(); |
const Class& instance_class = Class::Handle(instance.clazz()); |
- |
- if (instance_class.NumTypeArguments() > 0) { |
+ Object& instance_class_id_or_function = Object::Handle(); |
+ if (instance_class.IsClosureClass()) { |
+ instance_class_id_or_function = Closure::Cast(instance).function(); |
+ } else { |
+ instance_class_id_or_function = Smi::New(instance_class.id()); |
+ } |
+ TypeArguments& instance_type_arguments = TypeArguments::Handle(); |
+ if (instance_class.IsClosureClass() || |
+ (instance_class.NumTypeArguments() > 0)) { |
instance_type_arguments = instance.GetTypeArguments(); |
} |
@@ -377,20 +382,19 @@ static void UpdateTypeTestCache( |
instance_type_arguments.IsCanonical()); |
ASSERT(instantiator_type_arguments.IsNull() || |
instantiator_type_arguments.IsCanonical()); |
- intptr_t last_instance_class_id = -1; |
- TypeArguments& last_instance_type_arguments = |
- TypeArguments::Handle(); |
- TypeArguments& last_instantiator_type_arguments = |
- TypeArguments::Handle(); |
+ Object& last_instance_class_id_or_function = Object::Handle(); |
+ TypeArguments& last_instance_type_arguments = TypeArguments::Handle(); |
+ TypeArguments& last_instantiator_type_arguments = TypeArguments::Handle(); |
Bool& last_result = Bool::Handle(); |
for (intptr_t i = 0; i < len; ++i) { |
new_cache.GetCheck( |
i, |
- &last_instance_class_id, |
+ &last_instance_class_id_or_function, |
&last_instance_type_arguments, |
&last_instantiator_type_arguments, |
&last_result); |
- if ((last_instance_class_id == instance_class.id()) && |
+ if ((last_instance_class_id_or_function.raw() == |
+ instance_class_id_or_function.raw()) && |
(last_instance_type_arguments.raw() == instance_type_arguments.raw()) && |
(last_instantiator_type_arguments.raw() == |
instantiator_type_arguments.raw())) { |
@@ -402,7 +406,7 @@ static void UpdateTypeTestCache( |
} |
} |
#endif |
- new_cache.AddCheck(instance_class.id(), |
+ new_cache.AddCheck(instance_class_id_or_function, |
instance_type_arguments, |
instantiator_type_arguments, |
result); |
@@ -415,13 +419,13 @@ static void UpdateTypeTestCache( |
ASSERT(bound_error.IsNull()); // Malbounded types are not optimized. |
} |
OS::PrintErr(" Updated test cache %p ix: %" Pd " with " |
- "(cid: %" Pd ", type-args: %p, instantiator: %p, result: %s)\n" |
+ "(cid-or-fun: %p, type-args: %p, instantiator: %p, result: %s)\n" |
" instance [class: (%p '%s' cid: %" Pd "), type-args: %p %s]\n" |
" test-type [class: (%p '%s' cid: %" Pd "), in-type-args: %p %s]\n", |
new_cache.raw(), |
len, |
- instance_class.id(), |
+ instance_class_id_or_function.raw(), |
instance_type_arguments.raw(), |
instantiator_type_arguments.raw(), |
result.ToCString(), |
@@ -745,15 +749,8 @@ static bool ResolveCallThroughGetter(const Instance& receiver, |
if (getter.IsNull() || getter.IsMethodExtractor()) { |
return false; |
} |
- const Class& cache_class = Class::Handle(receiver_class.IsSignatureClass() |
- ? receiver_class.SuperClass() |
- : receiver_class.raw()); |
- ASSERT( |
- !receiver_class.IsSignatureClass() || |
- (receiver_class.SuperClass() == Type::Handle( |
- Isolate::Current()->object_store()->function_impl_type()).type_class())); |
const Function& target_function = |
- Function::Handle(cache_class.GetInvocationDispatcher( |
+ Function::Handle(receiver_class.GetInvocationDispatcher( |
target_name, |
arguments_descriptor, |
RawFunction::kInvokeFieldDispatcher, |
@@ -1223,15 +1220,14 @@ DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) { |
// Arg1: arguments descriptor array. |
// Arg2: arguments array. |
DEFINE_RUNTIME_ENTRY(InvokeClosureNoSuchMethod, 3) { |
- const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
+ const Closure& receiver = Closure::CheckedHandle(arguments.ArgAt(0)); |
const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(1)); |
const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(2)); |
// For closure the function name is always 'call'. Replace it with the |
// name of the closurized function so that exception contains more |
// relevant information. |
- ASSERT(receiver.IsClosure()); |
- const Function& function = Function::Handle(Closure::function(receiver)); |
+ const Function& function = Function::Handle(receiver.function()); |
const String& original_function_name = |
String::Handle(function.QualifiedUserVisibleName()); |
const Object& result = Object::Handle( |