Index: runtime/vm/object.cc |
=================================================================== |
--- runtime/vm/object.cc (revision 24991) |
+++ runtime/vm/object.cc (working copy) |
@@ -1518,7 +1518,8 @@ |
StorePointer(&raw_ptr()->canonical_types_, Object::empty_array().raw()); |
StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); |
StorePointer(&raw_ptr()->fields_, Object::empty_array().raw()); |
- StorePointer(&raw_ptr()->no_such_method_cache_, Object::empty_array().raw()); |
+ StorePointer(&raw_ptr()->invocation_dispatcher_cache_, |
+ Object::empty_array().raw()); |
} |
@@ -1774,8 +1775,9 @@ |
} |
-RawFunction* Class::GetNoSuchMethodDispatcher(const String& target_name, |
- const Array& args_desc) const { |
+RawFunction* Class::GetInvocationDispatcher(const String& target_name, |
+ const Array& args_desc, |
+ RawFunction::Kind kind) const { |
enum { |
kNameIndex = 0, |
kArgsDescIndex, |
@@ -1783,8 +1785,10 @@ |
kEntrySize |
}; |
+ ASSERT(kind == RawFunction::kNoSuchMethodDispatcher || |
+ kind == RawFunction::kInvokeFieldDispatcher); |
Function& dispatcher = Function::Handle(); |
- Array& cache = Array::Handle(no_such_method_cache()); |
+ Array& cache = Array::Handle(invocation_dispatcher_cache()); |
ASSERT(!cache.IsNull()); |
String& name = String::Handle(); |
Array& desc = Array::Handle(); |
@@ -1794,9 +1798,10 @@ |
if (name.IsNull()) break; // Reached last entry. |
if (!name.Equals(target_name)) continue; |
desc ^= cache.At(i + kArgsDescIndex); |
- if (desc.raw() == args_desc.raw()) { |
+ if (desc.raw() != args_desc.raw()) continue; |
+ dispatcher ^= cache.At(i + kFunctionIndex); |
+ if (dispatcher.kind() == kind) { |
// Found match. |
- dispatcher ^= cache.At(i + kFunctionIndex); |
ASSERT(dispatcher.IsFunction()); |
break; |
} |
@@ -1809,9 +1814,9 @@ |
? static_cast<intptr_t>(kEntrySize) |
: cache.Length() * 2; |
cache ^= Array::Grow(cache, new_len); |
- set_no_such_method_cache(cache); |
+ set_invocation_dispatcher_cache(cache); |
} |
- dispatcher ^= CreateNoSuchMethodDispatcher(target_name, args_desc); |
+ dispatcher ^= CreateInvocationDispatcher(target_name, args_desc, kind); |
cache.SetAt(i + kNameIndex, target_name); |
cache.SetAt(i + kArgsDescIndex, args_desc); |
cache.SetAt(i + kFunctionIndex, dispatcher); |
@@ -1820,11 +1825,12 @@ |
} |
-RawFunction* Class::CreateNoSuchMethodDispatcher(const String& target_name, |
- const Array& args_desc) const { |
+RawFunction* Class::CreateInvocationDispatcher(const String& target_name, |
+ const Array& args_desc, |
+ RawFunction::Kind kind) const { |
Function& invocation = Function::Handle( |
Function::New(String::Handle(Symbols::New(target_name)), |
- RawFunction::kNoSuchMethodDispatcher, |
+ kind, |
false, // Not static. |
false, // Not const. |
false, // Not abstract. |
@@ -1865,13 +1871,13 @@ |
} |
-RawArray* Class::no_such_method_cache() const { |
- return raw_ptr()->no_such_method_cache_; |
+RawArray* Class::invocation_dispatcher_cache() const { |
+ return raw_ptr()->invocation_dispatcher_cache_; |
} |
-void Class::set_no_such_method_cache(const Array& cache) const { |
- StorePointer(&raw_ptr()->no_such_method_cache_, cache.raw()); |
+void Class::set_invocation_dispatcher_cache(const Array& cache) const { |
+ StorePointer(&raw_ptr()->invocation_dispatcher_cache_, cache.raw()); |
} |
@@ -3716,7 +3722,8 @@ |
RawArray* Function::saved_args_desc() const { |
- ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher); |
+ ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || |
+ kind() == RawFunction::kInvokeFieldDispatcher); |
const Object& obj = Object::Handle(raw_ptr()->data_); |
ASSERT(obj.IsArray()); |
return Array::Cast(obj).raw(); |
@@ -3724,7 +3731,8 @@ |
void Function::set_saved_args_desc(const Array& value) const { |
- ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher); |
+ ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || |
+ kind() == RawFunction::kInvokeFieldDispatcher); |
ASSERT(raw_ptr()->data_ == Object::null()); |
set_data(value); |
} |
@@ -4874,6 +4882,9 @@ |
case RawFunction::kNoSuchMethodDispatcher: |
kind_str = " no-such-method-dispatcher"; |
break; |
+ case RawFunction::kInvokeFieldDispatcher: |
+ kind_str = "invoke-field-dispatcher"; |
+ break; |
default: |
UNREACHABLE(); |
} |