OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |