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. | |
srdjan
2013/07/09 15:20:28
WHy do you terminate on name being null AND on cac
Florian Schneider
2013/07/10 09:06:00
When growing by more than 1 element, the cache arr
| |
1770 if (!name.Equals(target_name)) continue; | |
1771 desc ^= cache.At(i + kArgsDescIndex); | |
1772 if (desc.raw() != args_desc.raw()) continue; | |
1773 // Found match. | |
1774 dispatcher ^= cache.At(i + kFunctionIndex); | |
1775 ASSERT(dispatcher.IsFunction()); | |
1776 break; | |
srdjan
2013/07/09 15:20:28
I believe this is simpler:
if (desc.raw() == args_
Florian Schneider
2013/07/10 09:06:00
Done.
| |
1777 } | |
1778 | |
1779 if (dispatcher.IsNull()) { | |
1780 if (i == cache.Length()) { | |
1781 // Allocate new larger cache. | |
1782 intptr_t new_len = cache.Length() == 0 ? kEntrySize : cache.Length() * 2; | |
srdjan
2013/07/09 15:35:40
Is it necessary to grow that aggressively? I would
Florian Schneider
2013/07/10 09:06:00
I don't think it matters, For the common case of f
| |
1783 cache ^= Array::Grow(cache, new_len); | |
1784 set_no_such_method_cache(cache); | |
1785 } | |
1786 dispatcher ^= CreateNoSuchMethodDispatcher(target_name, args_desc); | |
1787 cache.SetAt(i + kNameIndex, target_name); | |
1788 cache.SetAt(i + kArgsDescIndex, args_desc); | |
1789 cache.SetAt(i + kFunctionIndex, dispatcher); | |
1790 } | |
1791 return dispatcher.raw(); | |
1792 } | |
1793 | |
1794 | |
1795 RawFunction* Class::CreateNoSuchMethodDispatcher(const String& target_name, | |
1796 const Array& args_desc) const { | |
1797 Function& invocation = Function::Handle( | |
1798 Function::New(String::Handle(Symbols::New(target_name)), | |
1799 RawFunction::kNoSuchMethodDispatcher, | |
1800 false, // Not static. | |
1801 false, // Not const. | |
1802 false, // Not abstract. | |
1803 false, // Not external. | |
1804 *this, | |
1805 0)); // No token position. | |
1806 ArgumentsDescriptor desc(args_desc); | |
1807 const intptr_t num_parameters = desc.Count(); | |
1808 invocation.set_num_fixed_parameters(num_parameters); | |
1809 invocation.SetNumOptionalParameters(0, true); | |
1810 invocation.set_parameter_types(Array::Handle(Array::New(num_parameters, | |
1811 Heap::kOld))); | |
1812 invocation.set_parameter_names(Array::Handle(Array::New(num_parameters, | |
1813 Heap::kOld))); | |
1814 // Receiver. | |
1815 invocation.SetParameterTypeAt(0, Type::Handle(Type::DynamicType())); | |
1816 invocation.SetParameterNameAt(0, Symbols::This()); | |
1817 // Remaining parameters. | |
1818 for (intptr_t i = 1; i < num_parameters; i++) { | |
1819 invocation.SetParameterTypeAt(i, Type::Handle(Type::DynamicType())); | |
1820 char name[64]; | |
1821 OS::SNPrint(name, 64, ":p%"Pd, i); | |
1822 invocation.SetParameterNameAt(i, String::Handle(Symbols::New(name))); | |
1823 } | |
1824 invocation.set_result_type(Type::Handle(Type::DynamicType())); | |
1825 invocation.set_is_visible(false); // Not visible in stack trace. | |
1826 invocation.set_saved_args_desc(args_desc); | |
1827 | |
1828 return invocation.raw(); | |
1829 } | |
1830 | |
1831 | |
1832 RawArray* Class::no_such_method_cache() const { | |
1833 return raw_ptr()->no_such_method_cache_; | |
1834 } | |
1835 | |
1836 | |
1837 void Class::set_no_such_method_cache(const Array& cache) const { | |
1838 StorePointer(&raw_ptr()->no_such_method_cache_, cache.raw()); | |
1839 } | |
1840 | |
1841 | |
1751 void Class::Finalize() const { | 1842 void Class::Finalize() const { |
1752 ASSERT(!is_finalized()); | 1843 ASSERT(!is_finalized()); |
1753 // Prefinalized classes have a VM internal representation and no Dart fields. | 1844 // Prefinalized classes have a VM internal representation and no Dart fields. |
1754 // Their instance size is precomputed and field offsets are known. | 1845 // Their instance size is precomputed and field offsets are known. |
1755 if (!is_prefinalized()) { | 1846 if (!is_prefinalized()) { |
1756 // Compute offsets of instance fields and instance size. | 1847 // Compute offsets of instance fields and instance size. |
1757 CalculateFieldOffsets(); | 1848 CalculateFieldOffsets(); |
1758 } | 1849 } |
1759 set_is_finalized(); | 1850 set_is_finalized(); |
1760 } | 1851 } |
(...skipping 1787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3548 } | 3639 } |
3549 | 3640 |
3550 | 3641 |
3551 void Function::set_extracted_method_closure(const Function& value) const { | 3642 void Function::set_extracted_method_closure(const Function& value) const { |
3552 ASSERT(kind() == RawFunction::kMethodExtractor); | 3643 ASSERT(kind() == RawFunction::kMethodExtractor); |
3553 ASSERT(raw_ptr()->data_ == Object::null()); | 3644 ASSERT(raw_ptr()->data_ == Object::null()); |
3554 set_data(value); | 3645 set_data(value); |
3555 } | 3646 } |
3556 | 3647 |
3557 | 3648 |
3649 RawArray* Function::saved_args_desc() const { | |
3650 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher); | |
3651 const Object& obj = Object::Handle(raw_ptr()->data_); | |
3652 ASSERT(obj.IsArray()); | |
3653 return Array::Cast(obj).raw(); | |
3654 } | |
3655 | |
3656 | |
3657 void Function::set_saved_args_desc(const Array& value) const { | |
3658 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher); | |
3659 ASSERT(raw_ptr()->data_ == Object::null()); | |
3660 set_data(value); | |
3661 } | |
3662 | |
3663 | |
3558 RawFunction* Function::parent_function() const { | 3664 RawFunction* Function::parent_function() const { |
3559 if (IsClosureFunction()) { | 3665 if (IsClosureFunction()) { |
3560 const Object& obj = Object::Handle(raw_ptr()->data_); | 3666 const Object& obj = Object::Handle(raw_ptr()->data_); |
3561 ASSERT(!obj.IsNull()); | 3667 ASSERT(!obj.IsNull()); |
3562 return ClosureData::Cast(obj).parent_function(); | 3668 return ClosureData::Cast(obj).parent_function(); |
3563 } | 3669 } |
3564 return Function::null(); | 3670 return Function::null(); |
3565 } | 3671 } |
3566 | 3672 |
3567 | 3673 |
(...skipping 10097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13665 space); | 13771 space); |
13666 return reinterpret_cast<RawWeakProperty*>(raw); | 13772 return reinterpret_cast<RawWeakProperty*>(raw); |
13667 } | 13773 } |
13668 | 13774 |
13669 | 13775 |
13670 const char* WeakProperty::ToCString() const { | 13776 const char* WeakProperty::ToCString() const { |
13671 return "_WeakProperty"; | 13777 return "_WeakProperty"; |
13672 } | 13778 } |
13673 | 13779 |
13674 } // namespace dart | 13780 } // namespace dart |
OLD | NEW |