Chromium Code Reviews| 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 |