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

Side by Side Diff: runtime/vm/object.cc

Issue 18750004: Faster invocation of fields as methods. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 void Class::InitEmptyFields() { 1511 void Class::InitEmptyFields() {
1512 if (Object::empty_array().raw() == Array::null()) { 1512 if (Object::empty_array().raw() == Array::null()) {
1513 // The empty array has not been initialized yet. 1513 // The empty array has not been initialized yet.
1514 return; 1514 return;
1515 } 1515 }
1516 StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw()); 1516 StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw());
1517 StorePointer(&raw_ptr()->constants_, Object::empty_array().raw()); 1517 StorePointer(&raw_ptr()->constants_, Object::empty_array().raw());
1518 StorePointer(&raw_ptr()->canonical_types_, Object::empty_array().raw()); 1518 StorePointer(&raw_ptr()->canonical_types_, Object::empty_array().raw());
1519 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); 1519 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw());
1520 StorePointer(&raw_ptr()->fields_, Object::empty_array().raw()); 1520 StorePointer(&raw_ptr()->fields_, Object::empty_array().raw());
1521 StorePointer(&raw_ptr()->no_such_method_cache_, Object::empty_array().raw()); 1521 StorePointer(&raw_ptr()->invocation_dispatcher_cache_,
1522 Object::empty_array().raw());
1522 } 1523 }
1523 1524
1524 1525
1525 bool Class::HasInstanceFields() const { 1526 bool Class::HasInstanceFields() const {
1526 const Array& field_array = Array::Handle(fields()); 1527 const Array& field_array = Array::Handle(fields());
1527 Field& field = Field::Handle(); 1528 Field& field = Field::Handle();
1528 for (intptr_t i = 0; i < field_array.Length(); ++i) { 1529 for (intptr_t i = 0; i < field_array.Length(); ++i) {
1529 field ^= field_array.At(i); 1530 field ^= field_array.At(i);
1530 if (!field.is_static()) { 1531 if (!field.is_static()) {
1531 return true; 1532 return true;
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 ASSERT(field.Offset() == 0); 1768 ASSERT(field.Offset() == 0);
1768 field.SetOffset(offset); 1769 field.SetOffset(offset);
1769 offset += kWordSize; 1770 offset += kWordSize;
1770 } 1771 }
1771 } 1772 }
1772 set_instance_size(RoundedAllocationSize(offset)); 1773 set_instance_size(RoundedAllocationSize(offset));
1773 set_next_field_offset(offset); 1774 set_next_field_offset(offset);
1774 } 1775 }
1775 1776
1776 1777
1777 RawFunction* Class::GetNoSuchMethodDispatcher(const String& target_name, 1778 RawFunction* Class::GetInvocationDispatcher(const String& target_name,
1778 const Array& args_desc) const { 1779 const Array& args_desc,
1780 RawFunction::Kind kind) const {
1779 enum { 1781 enum {
1780 kNameIndex = 0, 1782 kNameIndex = 0,
1781 kArgsDescIndex, 1783 kArgsDescIndex,
1782 kFunctionIndex, 1784 kFunctionIndex,
1783 kEntrySize 1785 kEntrySize
1784 }; 1786 };
1785 1787
1788 ASSERT(kind == RawFunction::kNoSuchMethodDispatcher ||
1789 kind == RawFunction::kInvokeFieldDispatcher);
1786 Function& dispatcher = Function::Handle(); 1790 Function& dispatcher = Function::Handle();
1787 Array& cache = Array::Handle(no_such_method_cache()); 1791 Array& cache = Array::Handle(invocation_dispatcher_cache());
1788 ASSERT(!cache.IsNull()); 1792 ASSERT(!cache.IsNull());
1789 String& name = String::Handle(); 1793 String& name = String::Handle();
1790 Array& desc = Array::Handle(); 1794 Array& desc = Array::Handle();
1791 intptr_t i = 0; 1795 intptr_t i = 0;
1792 for (; i < cache.Length(); i += kEntrySize) { 1796 for (; i < cache.Length(); i += kEntrySize) {
1793 name ^= cache.At(i + kNameIndex); 1797 name ^= cache.At(i + kNameIndex);
1794 if (name.IsNull()) break; // Reached last entry. 1798 if (name.IsNull()) break; // Reached last entry.
1795 if (!name.Equals(target_name)) continue; 1799 if (!name.Equals(target_name)) continue;
1796 desc ^= cache.At(i + kArgsDescIndex); 1800 desc ^= cache.At(i + kArgsDescIndex);
1797 if (desc.raw() == args_desc.raw()) { 1801 if (desc.raw() != args_desc.raw()) continue;
1802 dispatcher ^= cache.At(i + kFunctionIndex);
1803 if (dispatcher.kind() == kind) {
1798 // Found match. 1804 // Found match.
1799 dispatcher ^= cache.At(i + kFunctionIndex);
1800 ASSERT(dispatcher.IsFunction()); 1805 ASSERT(dispatcher.IsFunction());
1801 break; 1806 break;
1802 } 1807 }
1803 } 1808 }
1804 1809
1805 if (dispatcher.IsNull()) { 1810 if (dispatcher.IsNull()) {
1806 if (i == cache.Length()) { 1811 if (i == cache.Length()) {
1807 // Allocate new larger cache. 1812 // Allocate new larger cache.
1808 intptr_t new_len = (cache.Length() == 0) 1813 intptr_t new_len = (cache.Length() == 0)
1809 ? static_cast<intptr_t>(kEntrySize) 1814 ? static_cast<intptr_t>(kEntrySize)
1810 : cache.Length() * 2; 1815 : cache.Length() * 2;
1811 cache ^= Array::Grow(cache, new_len); 1816 cache ^= Array::Grow(cache, new_len);
1812 set_no_such_method_cache(cache); 1817 set_invocation_dispatcher_cache(cache);
1813 } 1818 }
1814 dispatcher ^= CreateNoSuchMethodDispatcher(target_name, args_desc); 1819 dispatcher ^= CreateInvocationDispatcher(target_name, args_desc, kind);
1815 cache.SetAt(i + kNameIndex, target_name); 1820 cache.SetAt(i + kNameIndex, target_name);
1816 cache.SetAt(i + kArgsDescIndex, args_desc); 1821 cache.SetAt(i + kArgsDescIndex, args_desc);
1817 cache.SetAt(i + kFunctionIndex, dispatcher); 1822 cache.SetAt(i + kFunctionIndex, dispatcher);
1818 } 1823 }
1819 return dispatcher.raw(); 1824 return dispatcher.raw();
1820 } 1825 }
1821 1826
1822 1827
1823 RawFunction* Class::CreateNoSuchMethodDispatcher(const String& target_name, 1828 RawFunction* Class::CreateInvocationDispatcher(const String& target_name,
1824 const Array& args_desc) const { 1829 const Array& args_desc,
1830 RawFunction::Kind kind) const {
1825 Function& invocation = Function::Handle( 1831 Function& invocation = Function::Handle(
1826 Function::New(String::Handle(Symbols::New(target_name)), 1832 Function::New(String::Handle(Symbols::New(target_name)),
1827 RawFunction::kNoSuchMethodDispatcher, 1833 kind,
1828 false, // Not static. 1834 false, // Not static.
1829 false, // Not const. 1835 false, // Not const.
1830 false, // Not abstract. 1836 false, // Not abstract.
1831 false, // Not external. 1837 false, // Not external.
1832 *this, 1838 *this,
1833 0)); // No token position. 1839 0)); // No token position.
1834 ArgumentsDescriptor desc(args_desc); 1840 ArgumentsDescriptor desc(args_desc);
1835 invocation.set_num_fixed_parameters(desc.PositionalCount()); 1841 invocation.set_num_fixed_parameters(desc.PositionalCount());
1836 invocation.SetNumOptionalParameters(desc.NamedCount(), 1842 invocation.SetNumOptionalParameters(desc.NamedCount(),
1837 false); // Not positional. 1843 false); // Not positional.
(...skipping 20 matching lines...) Expand all
1858 invocation.SetParameterNameAt(i, String::Handle(desc.NameAt(index))); 1864 invocation.SetParameterNameAt(i, String::Handle(desc.NameAt(index)));
1859 } 1865 }
1860 invocation.set_result_type(Type::Handle(Type::DynamicType())); 1866 invocation.set_result_type(Type::Handle(Type::DynamicType()));
1861 invocation.set_is_visible(false); // Not visible in stack trace. 1867 invocation.set_is_visible(false); // Not visible in stack trace.
1862 invocation.set_saved_args_desc(args_desc); 1868 invocation.set_saved_args_desc(args_desc);
1863 1869
1864 return invocation.raw(); 1870 return invocation.raw();
1865 } 1871 }
1866 1872
1867 1873
1868 RawArray* Class::no_such_method_cache() const { 1874 RawArray* Class::invocation_dispatcher_cache() const {
1869 return raw_ptr()->no_such_method_cache_; 1875 return raw_ptr()->invocation_dispatcher_cache_;
1870 } 1876 }
1871 1877
1872 1878
1873 void Class::set_no_such_method_cache(const Array& cache) const { 1879 void Class::set_invocation_dispatcher_cache(const Array& cache) const {
1874 StorePointer(&raw_ptr()->no_such_method_cache_, cache.raw()); 1880 StorePointer(&raw_ptr()->invocation_dispatcher_cache_, cache.raw());
1875 } 1881 }
1876 1882
1877 1883
1878 void Class::Finalize() const { 1884 void Class::Finalize() const {
1879 ASSERT(!is_finalized()); 1885 ASSERT(!is_finalized());
1880 // Prefinalized classes have a VM internal representation and no Dart fields. 1886 // Prefinalized classes have a VM internal representation and no Dart fields.
1881 // Their instance size is precomputed and field offsets are known. 1887 // Their instance size is precomputed and field offsets are known.
1882 if (!is_prefinalized()) { 1888 if (!is_prefinalized()) {
1883 // Compute offsets of instance fields and instance size. 1889 // Compute offsets of instance fields and instance size.
1884 CalculateFieldOffsets(); 1890 CalculateFieldOffsets();
(...skipping 1824 matching lines...) Expand 10 before | Expand all | Expand 10 after
3709 3715
3710 3716
3711 void Function::set_extracted_method_closure(const Function& value) const { 3717 void Function::set_extracted_method_closure(const Function& value) const {
3712 ASSERT(kind() == RawFunction::kMethodExtractor); 3718 ASSERT(kind() == RawFunction::kMethodExtractor);
3713 ASSERT(raw_ptr()->data_ == Object::null()); 3719 ASSERT(raw_ptr()->data_ == Object::null());
3714 set_data(value); 3720 set_data(value);
3715 } 3721 }
3716 3722
3717 3723
3718 RawArray* Function::saved_args_desc() const { 3724 RawArray* Function::saved_args_desc() const {
3719 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher); 3725 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher ||
3726 kind() == RawFunction::kInvokeFieldDispatcher);
3720 const Object& obj = Object::Handle(raw_ptr()->data_); 3727 const Object& obj = Object::Handle(raw_ptr()->data_);
3721 ASSERT(obj.IsArray()); 3728 ASSERT(obj.IsArray());
3722 return Array::Cast(obj).raw(); 3729 return Array::Cast(obj).raw();
3723 } 3730 }
3724 3731
3725 3732
3726 void Function::set_saved_args_desc(const Array& value) const { 3733 void Function::set_saved_args_desc(const Array& value) const {
3727 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher); 3734 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher ||
3735 kind() == RawFunction::kInvokeFieldDispatcher);
3728 ASSERT(raw_ptr()->data_ == Object::null()); 3736 ASSERT(raw_ptr()->data_ == Object::null());
3729 set_data(value); 3737 set_data(value);
3730 } 3738 }
3731 3739
3732 3740
3733 RawFunction* Function::parent_function() const { 3741 RawFunction* Function::parent_function() const {
3734 if (IsClosureFunction()) { 3742 if (IsClosureFunction()) {
3735 const Object& obj = Object::Handle(raw_ptr()->data_); 3743 const Object& obj = Object::Handle(raw_ptr()->data_);
3736 ASSERT(!obj.IsNull()); 3744 ASSERT(!obj.IsNull());
3737 return ClosureData::Cast(obj).parent_function(); 3745 return ClosureData::Cast(obj).parent_function();
(...skipping 1129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4867 break; 4875 break;
4868 case RawFunction::kConstImplicitGetter: 4876 case RawFunction::kConstImplicitGetter:
4869 kind_str = " const-getter"; 4877 kind_str = " const-getter";
4870 break; 4878 break;
4871 case RawFunction::kMethodExtractor: 4879 case RawFunction::kMethodExtractor:
4872 kind_str = " method-extractor"; 4880 kind_str = " method-extractor";
4873 break; 4881 break;
4874 case RawFunction::kNoSuchMethodDispatcher: 4882 case RawFunction::kNoSuchMethodDispatcher:
4875 kind_str = " no-such-method-dispatcher"; 4883 kind_str = " no-such-method-dispatcher";
4876 break; 4884 break;
4885 case RawFunction::kInvokeFieldDispatcher:
4886 kind_str = "invoke-field-dispatcher";
4887 break;
4877 default: 4888 default:
4878 UNREACHABLE(); 4889 UNREACHABLE();
4879 } 4890 }
4880 const char* kFormat = "Function '%s':%s%s%s%s."; 4891 const char* kFormat = "Function '%s':%s%s%s%s.";
4881 const char* function_name = String::Handle(name()).ToCString(); 4892 const char* function_name = String::Handle(name()).ToCString();
4882 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, 4893 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name,
4883 static_str, abstract_str, kind_str, const_str) + 1; 4894 static_str, abstract_str, kind_str, const_str) + 1;
4884 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 4895 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
4885 OS::SNPrint(chars, len, kFormat, function_name, 4896 OS::SNPrint(chars, len, kFormat, function_name,
4886 static_str, abstract_str, kind_str, const_str); 4897 static_str, abstract_str, kind_str, const_str);
(...skipping 9261 matching lines...) Expand 10 before | Expand all | Expand 10 after
14148 } 14159 }
14149 14160
14150 14161
14151 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 14162 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
14152 stream->OpenObject(); 14163 stream->OpenObject();
14153 stream->CloseObject(); 14164 stream->CloseObject();
14154 } 14165 }
14155 14166
14156 14167
14157 } // namespace dart 14168 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698