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 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |