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

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

Issue 18097004: Support fast noSuchMethod dispatch for any number of arguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments 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
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 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 void Class::InitEmptyFields() { 1485 void Class::InitEmptyFields() {
1486 if (Object::empty_array().raw() == Array::null()) { 1486 if (Object::empty_array().raw() == Array::null()) {
1487 // The empty array has not been initialized yet. 1487 // The empty array has not been initialized yet.
1488 return; 1488 return;
1489 } 1489 }
1490 StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw()); 1490 StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw());
1491 StorePointer(&raw_ptr()->constants_, Object::empty_array().raw()); 1491 StorePointer(&raw_ptr()->constants_, Object::empty_array().raw());
1492 StorePointer(&raw_ptr()->canonical_types_, Object::empty_array().raw()); 1492 StorePointer(&raw_ptr()->canonical_types_, Object::empty_array().raw());
1493 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); 1493 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw());
1494 StorePointer(&raw_ptr()->fields_, Object::empty_array().raw()); 1494 StorePointer(&raw_ptr()->fields_, Object::empty_array().raw());
1495 StorePointer(&raw_ptr()->no_such_method_cache_, Object::empty_array().raw());
1495 } 1496 }
1496 1497
1497 1498
1498 bool Class::HasInstanceFields() const { 1499 bool Class::HasInstanceFields() const {
1499 const Array& field_array = Array::Handle(fields()); 1500 const Array& field_array = Array::Handle(fields());
1500 Field& field = Field::Handle(); 1501 Field& field = Field::Handle();
1501 for (intptr_t i = 0; i < field_array.Length(); ++i) { 1502 for (intptr_t i = 0; i < field_array.Length(); ++i) {
1502 field ^= field_array.At(i); 1503 field ^= field_array.At(i);
1503 if (!field.is_static()) { 1504 if (!field.is_static()) {
1504 return true; 1505 return true;
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1741 ASSERT(field.Offset() == 0); 1742 ASSERT(field.Offset() == 0);
1742 field.SetOffset(offset); 1743 field.SetOffset(offset);
1743 offset += kWordSize; 1744 offset += kWordSize;
1744 } 1745 }
1745 } 1746 }
1746 set_instance_size(RoundedAllocationSize(offset)); 1747 set_instance_size(RoundedAllocationSize(offset));
1747 set_next_field_offset(offset); 1748 set_next_field_offset(offset);
1748 } 1749 }
1749 1750
1750 1751
1752 RawFunction* Class::GetNoSuchMethodDispatcher(const String& target_name,
1753 const Array& args_desc) const {
1754 enum {
1755 kNameIndex = 0,
1756 kArgsDescIndex,
1757 kFunctionIndex,
1758 kEntrySize
1759 };
1760
1761 Function& dispatcher = Function::Handle();
1762 Array& cache = Array::Handle(no_such_method_cache());
1763 ASSERT(!cache.IsNull());
1764 String& name = String::Handle();
1765 Array& desc = Array::Handle();
1766 intptr_t i = 0;
1767 for (; i < cache.Length(); i += kEntrySize) {
1768 name ^= cache.At(i + kNameIndex);
1769 if (name.IsNull()) break; // Reached last entry.
1770 if (!name.Equals(target_name)) continue;
1771 desc ^= cache.At(i + kArgsDescIndex);
1772 if (desc.raw() == args_desc.raw()) {
1773 // Found match.
1774 dispatcher ^= cache.At(i + kFunctionIndex);
1775 ASSERT(dispatcher.IsFunction());
1776 break;
1777 }
1778 }
1779
1780 if (dispatcher.IsNull()) {
1781 if (i == cache.Length()) {
1782 // Allocate new larger cache.
1783 intptr_t new_len = cache.Length() == 0 ? kEntrySize : cache.Length() * 2;
1784 cache ^= Array::Grow(cache, new_len);
1785 set_no_such_method_cache(cache);
1786 }
1787 dispatcher ^= CreateNoSuchMethodDispatcher(target_name, args_desc);
1788 cache.SetAt(i + kNameIndex, target_name);
1789 cache.SetAt(i + kArgsDescIndex, args_desc);
1790 cache.SetAt(i + kFunctionIndex, dispatcher);
1791 }
1792 return dispatcher.raw();
1793 }
1794
1795
1796 RawFunction* Class::CreateNoSuchMethodDispatcher(const String& target_name,
1797 const Array& args_desc) const {
1798 Function& invocation = Function::Handle(
1799 Function::New(String::Handle(Symbols::New(target_name)),
1800 RawFunction::kNoSuchMethodDispatcher,
1801 false, // Not static.
1802 false, // Not const.
1803 false, // Not abstract.
1804 false, // Not external.
1805 *this,
1806 0)); // No token position.
1807 ArgumentsDescriptor desc(args_desc);
1808 const intptr_t num_parameters = desc.Count();
1809 invocation.set_num_fixed_parameters(num_parameters);
1810 invocation.SetNumOptionalParameters(0, true);
1811 invocation.set_parameter_types(Array::Handle(Array::New(num_parameters,
1812 Heap::kOld)));
1813 invocation.set_parameter_names(Array::Handle(Array::New(num_parameters,
1814 Heap::kOld)));
1815 // Receiver.
1816 invocation.SetParameterTypeAt(0, Type::Handle(Type::DynamicType()));
1817 invocation.SetParameterNameAt(0, Symbols::This());
1818 // Remaining parameters.
1819 for (intptr_t i = 1; i < num_parameters; i++) {
1820 invocation.SetParameterTypeAt(i, Type::Handle(Type::DynamicType()));
1821 char name[64];
1822 OS::SNPrint(name, 64, ":p%"Pd, i);
1823 invocation.SetParameterNameAt(i, String::Handle(Symbols::New(name)));
1824 }
1825 invocation.set_result_type(Type::Handle(Type::DynamicType()));
1826 invocation.set_is_visible(false); // Not visible in stack trace.
1827 invocation.set_saved_args_desc(args_desc);
1828
1829 return invocation.raw();
1830 }
1831
1832
1833 RawArray* Class::no_such_method_cache() const {
1834 return raw_ptr()->no_such_method_cache_;
1835 }
1836
1837
1838 void Class::set_no_such_method_cache(const Array& cache) const {
1839 StorePointer(&raw_ptr()->no_such_method_cache_, cache.raw());
1840 }
1841
1842
1751 void Class::Finalize() const { 1843 void Class::Finalize() const {
1752 ASSERT(!is_finalized()); 1844 ASSERT(!is_finalized());
1753 // Prefinalized classes have a VM internal representation and no Dart fields. 1845 // Prefinalized classes have a VM internal representation and no Dart fields.
1754 // Their instance size is precomputed and field offsets are known. 1846 // Their instance size is precomputed and field offsets are known.
1755 if (!is_prefinalized()) { 1847 if (!is_prefinalized()) {
1756 // Compute offsets of instance fields and instance size. 1848 // Compute offsets of instance fields and instance size.
1757 CalculateFieldOffsets(); 1849 CalculateFieldOffsets();
1758 } 1850 }
1759 set_is_finalized(); 1851 set_is_finalized();
1760 } 1852 }
(...skipping 1787 matching lines...) Expand 10 before | Expand all | Expand 10 after
3548 } 3640 }
3549 3641
3550 3642
3551 void Function::set_extracted_method_closure(const Function& value) const { 3643 void Function::set_extracted_method_closure(const Function& value) const {
3552 ASSERT(kind() == RawFunction::kMethodExtractor); 3644 ASSERT(kind() == RawFunction::kMethodExtractor);
3553 ASSERT(raw_ptr()->data_ == Object::null()); 3645 ASSERT(raw_ptr()->data_ == Object::null());
3554 set_data(value); 3646 set_data(value);
3555 } 3647 }
3556 3648
3557 3649
3650 RawArray* Function::saved_args_desc() const {
3651 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher);
3652 const Object& obj = Object::Handle(raw_ptr()->data_);
3653 ASSERT(obj.IsArray());
3654 return Array::Cast(obj).raw();
3655 }
3656
3657
3658 void Function::set_saved_args_desc(const Array& value) const {
3659 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher);
3660 ASSERT(raw_ptr()->data_ == Object::null());
3661 set_data(value);
3662 }
3663
3664
3558 RawFunction* Function::parent_function() const { 3665 RawFunction* Function::parent_function() const {
3559 if (IsClosureFunction()) { 3666 if (IsClosureFunction()) {
3560 const Object& obj = Object::Handle(raw_ptr()->data_); 3667 const Object& obj = Object::Handle(raw_ptr()->data_);
3561 ASSERT(!obj.IsNull()); 3668 ASSERT(!obj.IsNull());
3562 return ClosureData::Cast(obj).parent_function(); 3669 return ClosureData::Cast(obj).parent_function();
3563 } 3670 }
3564 return Function::null(); 3671 return Function::null();
3565 } 3672 }
3566 3673
3567 3674
(...skipping 10097 matching lines...) Expand 10 before | Expand all | Expand 10 after
13665 space); 13772 space);
13666 return reinterpret_cast<RawWeakProperty*>(raw); 13773 return reinterpret_cast<RawWeakProperty*>(raw);
13667 } 13774 }
13668 13775
13669 13776
13670 const char* WeakProperty::ToCString() const { 13777 const char* WeakProperty::ToCString() const {
13671 return "_WeakProperty"; 13778 return "_WeakProperty";
13672 } 13779 }
13673 13780
13674 } // namespace dart 13781 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698