| 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();
|
| }
|
|
|