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/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 90 RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
91 RawClass* Object::stackmap_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 91 RawClass* Object::stackmap_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
92 RawClass* Object::var_descriptors_class_ = | 92 RawClass* Object::var_descriptors_class_ = |
93 reinterpret_cast<RawClass*>(RAW_NULL); | 93 reinterpret_cast<RawClass*>(RAW_NULL); |
94 RawClass* Object::exception_handlers_class_ = | 94 RawClass* Object::exception_handlers_class_ = |
95 reinterpret_cast<RawClass*>(RAW_NULL); | 95 reinterpret_cast<RawClass*>(RAW_NULL); |
96 RawClass* Object::deopt_info_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 96 RawClass* Object::deopt_info_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
97 RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 97 RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
98 RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 98 RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
99 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 99 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
100 RawClass* Object::megamorphic_cache_class_ = | |
101 reinterpret_cast<RawClass*>(RAW_NULL); | |
100 RawClass* Object::subtypetestcache_class_ = | 102 RawClass* Object::subtypetestcache_class_ = |
101 reinterpret_cast<RawClass*>(RAW_NULL); | 103 reinterpret_cast<RawClass*>(RAW_NULL); |
102 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 104 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
103 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 105 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
104 RawClass* Object::unhandled_exception_class_ = | 106 RawClass* Object::unhandled_exception_class_ = |
105 reinterpret_cast<RawClass*>(RAW_NULL); | 107 reinterpret_cast<RawClass*>(RAW_NULL); |
106 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 108 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
107 #undef RAW_NULL | 109 #undef RAW_NULL |
108 | 110 |
109 | 111 |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
375 | 377 |
376 cls = Class::New<Context>(); | 378 cls = Class::New<Context>(); |
377 context_class_ = cls.raw(); | 379 context_class_ = cls.raw(); |
378 | 380 |
379 cls = Class::New<ContextScope>(); | 381 cls = Class::New<ContextScope>(); |
380 context_scope_class_ = cls.raw(); | 382 context_scope_class_ = cls.raw(); |
381 | 383 |
382 cls = Class::New<ICData>(); | 384 cls = Class::New<ICData>(); |
383 icdata_class_ = cls.raw(); | 385 icdata_class_ = cls.raw(); |
384 | 386 |
387 cls = Class::New<MegamorphicCache>(); | |
388 megamorphic_cache_class_ = cls.raw(); | |
389 | |
385 cls = Class::New<SubtypeTestCache>(); | 390 cls = Class::New<SubtypeTestCache>(); |
386 subtypetestcache_class_ = cls.raw(); | 391 subtypetestcache_class_ = cls.raw(); |
387 | 392 |
388 cls = Class::New<ApiError>(); | 393 cls = Class::New<ApiError>(); |
389 api_error_class_ = cls.raw(); | 394 api_error_class_ = cls.raw(); |
390 | 395 |
391 cls = Class::New<LanguageError>(); | 396 cls = Class::New<LanguageError>(); |
392 language_error_class_ = cls.raw(); | 397 language_error_class_ = cls.raw(); |
393 | 398 |
394 cls = Class::New<UnhandledException>(); | 399 cls = Class::New<UnhandledException>(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
450 SET_CLASS_NAME(code, Code); | 455 SET_CLASS_NAME(code, Code); |
451 SET_CLASS_NAME(instructions, Instructions); | 456 SET_CLASS_NAME(instructions, Instructions); |
452 SET_CLASS_NAME(pc_descriptors, PcDescriptors); | 457 SET_CLASS_NAME(pc_descriptors, PcDescriptors); |
453 SET_CLASS_NAME(stackmap, Stackmap); | 458 SET_CLASS_NAME(stackmap, Stackmap); |
454 SET_CLASS_NAME(var_descriptors, LocalVarDescriptors); | 459 SET_CLASS_NAME(var_descriptors, LocalVarDescriptors); |
455 SET_CLASS_NAME(exception_handlers, ExceptionHandlers); | 460 SET_CLASS_NAME(exception_handlers, ExceptionHandlers); |
456 SET_CLASS_NAME(deopt_info, DeoptInfo); | 461 SET_CLASS_NAME(deopt_info, DeoptInfo); |
457 SET_CLASS_NAME(context, Context); | 462 SET_CLASS_NAME(context, Context); |
458 SET_CLASS_NAME(context_scope, ContextScope); | 463 SET_CLASS_NAME(context_scope, ContextScope); |
459 SET_CLASS_NAME(icdata, ICData); | 464 SET_CLASS_NAME(icdata, ICData); |
465 SET_CLASS_NAME(megamorphic_cache, MegamorphicCache); | |
460 SET_CLASS_NAME(subtypetestcache, SubtypeTestCache); | 466 SET_CLASS_NAME(subtypetestcache, SubtypeTestCache); |
461 SET_CLASS_NAME(api_error, ApiError); | 467 SET_CLASS_NAME(api_error, ApiError); |
462 SET_CLASS_NAME(language_error, LanguageError); | 468 SET_CLASS_NAME(language_error, LanguageError); |
463 SET_CLASS_NAME(unhandled_exception, UnhandledException); | 469 SET_CLASS_NAME(unhandled_exception, UnhandledException); |
464 SET_CLASS_NAME(unwind_error, UnwindError); | 470 SET_CLASS_NAME(unwind_error, UnwindError); |
465 | 471 |
466 // Set up names for object array and one byte string class which are | 472 // Set up names for object array and one byte string class which are |
467 // pre-allocated in the vm isolate also. | 473 // pre-allocated in the vm isolate also. |
468 cls = Dart::vm_isolate()->object_store()->array_class(); | 474 cls = Dart::vm_isolate()->object_store()->array_class(); |
469 str = Symbols::ObjectArray(); | 475 str = Symbols::ObjectArray(); |
(...skipping 7281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7751 // Number of array elements in one test entry. | 7757 // Number of array elements in one test entry. |
7752 intptr_t len = result.TestEntryLength(); | 7758 intptr_t len = result.TestEntryLength(); |
7753 // IC data array must be null terminated (sentinel entry). | 7759 // IC data array must be null terminated (sentinel entry). |
7754 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); | 7760 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); |
7755 result.set_ic_data(ic_data); | 7761 result.set_ic_data(ic_data); |
7756 result.WriteSentinel(); | 7762 result.WriteSentinel(); |
7757 return result.raw(); | 7763 return result.raw(); |
7758 } | 7764 } |
7759 | 7765 |
7760 | 7766 |
7767 RawArray* MegamorphicCache::buckets() const { | |
7768 return raw_ptr()->buckets_; | |
7769 } | |
7770 | |
7771 | |
7772 void MegamorphicCache::set_buckets(const Array& buckets) const { | |
7773 StorePointer(&raw_ptr()->buckets_, buckets.raw()); | |
7774 } | |
7775 | |
7776 | |
7777 // Class IDs in the table are smi-tagged, so we use a smi-tagged mask | |
7778 // and target class ID to avoid untagging (on each iteration of the | |
7779 // test loop) in generated code. | |
7780 intptr_t MegamorphicCache::mask() const { | |
7781 return Smi::Value(raw_ptr()->mask_); | |
7782 } | |
7783 | |
7784 | |
7785 void MegamorphicCache::set_mask(intptr_t mask) const { | |
7786 raw_ptr()->mask_ = Smi::New(mask); | |
7787 } | |
7788 | |
7789 | |
7790 intptr_t MegamorphicCache::fill_count() const { | |
7791 return raw_ptr()->fill_count_; | |
7792 } | |
7793 | |
7794 | |
7795 void MegamorphicCache::set_fill_count(intptr_t fill_count) const { | |
7796 raw_ptr()->fill_count_ = fill_count; | |
7797 } | |
7798 | |
7799 | |
7800 RawMegamorphicCache* MegamorphicCache::New() { | |
7801 MegamorphicCache& result = MegamorphicCache::Handle(); | |
7802 { RawObject* raw = Object::Allocate(MegamorphicCache::kClassId, | |
7803 MegamorphicCache::InstanceSize(), | |
7804 Heap::kOld); | |
7805 NoGCScope no_gc; | |
7806 result ^= raw; | |
7807 } | |
7808 const intptr_t size = kInitialCapacity; | |
7809 const Array& buckets = Array::Handle(Array::New(2 * size)); | |
7810 const Smi& illegal = Smi::Handle(Smi::New(kIllegalCid)); | |
7811 const Function& handler = Function::Handle( | |
7812 Isolate::Current()->megamorphic_cache_table()->miss_handler()); | |
7813 for (intptr_t i = 0; i < size; ++i) { | |
7814 buckets.SetAt(2 * i, illegal); | |
Vyacheslav Egorov (Google)
2012/12/03 14:55:22
I don't like magical constant spread around
Kevin Millikin (Google)
2012/12/06 14:03:11
I thought this was already pretty localized, but I
| |
7815 buckets.SetAt((2 * i) + 1, handler); | |
7816 } | |
7817 result.set_buckets(buckets); | |
7818 result.set_mask(size - 1); | |
7819 result.set_fill_count(0); | |
7820 return result.raw(); | |
7821 } | |
7822 | |
7823 | |
7824 void MegamorphicCache::EnsureCapacity() const { | |
7825 intptr_t old_size = mask() + 1; | |
7826 double load_limit = kLoadFactor * static_cast<double>(old_size); | |
7827 if (static_cast<double>(fill_count() + 1) > load_limit) { | |
7828 const Array& old_buckets = Array::Handle(buckets()); | |
7829 intptr_t new_size = old_size * 2; | |
7830 const Array& new_buckets = Array::Handle(Array::New(2 * new_size)); | |
7831 | |
7832 Smi& class_id = Smi::Handle(Smi::New(kIllegalCid)); | |
7833 Function& target = Function::Handle( | |
7834 Isolate::Current()->megamorphic_cache_table()->miss_handler()); | |
7835 for (intptr_t i = 0; i < new_size; ++i) { | |
7836 new_buckets.SetAt(2 * i, class_id); | |
7837 new_buckets.SetAt((2 * i) + 1, target); | |
7838 } | |
7839 set_buckets(new_buckets); | |
7840 set_mask(new_size - 1); | |
7841 set_fill_count(0); | |
7842 | |
7843 // Rehash the valid entries. | |
7844 for (intptr_t i = 0; i < old_size; ++i) { | |
7845 class_id ^= old_buckets.At(2 * i); | |
7846 if (class_id.Value() != kIllegalCid) { | |
7847 target ^= old_buckets.At((2 * i) + 1); | |
7848 Insert(class_id, target); | |
7849 } | |
7850 } | |
7851 } | |
7852 } | |
7853 | |
7854 | |
7855 void MegamorphicCache::Insert(const Smi& class_id, | |
7856 const Function& target) const { | |
7857 ASSERT(static_cast<double>(fill_count() + 1) <= | |
7858 (kLoadFactor * static_cast<double>(mask() + 1))); | |
7859 const Array& backing_array = Array::Handle(buckets()); | |
7860 intptr_t id_mask = mask(); | |
7861 intptr_t index = class_id.Value() & id_mask; | |
7862 Smi& probe = Smi::Handle(); | |
7863 intptr_t i = index; | |
7864 do { | |
7865 probe ^= backing_array.At(2 * i); | |
7866 if (probe.Value() == kIllegalCid) { | |
7867 backing_array.SetAt(2 * i, class_id); | |
7868 backing_array.SetAt((2 * i) + 1, target); | |
7869 set_fill_count(fill_count() + 1); | |
Vyacheslav Egorov (Google)
2012/12/03 14:55:22
consider renaming fill_count to size
Kevin Millikin (Google)
2012/12/06 14:03:11
Since variables ending in _size are always in byte
| |
7870 return; | |
7871 } | |
7872 i = (i + 1) & id_mask; | |
7873 } while (i != index); | |
7874 UNREACHABLE(); | |
7875 } | |
7876 | |
7877 | |
7878 const char* MegamorphicCache::ToCString() const { | |
7879 return ""; | |
7880 } | |
7881 | |
7882 | |
7761 RawSubtypeTestCache* SubtypeTestCache::New() { | 7883 RawSubtypeTestCache* SubtypeTestCache::New() { |
7762 ASSERT(Object::subtypetestcache_class() != Class::null()); | 7884 ASSERT(Object::subtypetestcache_class() != Class::null()); |
7763 SubtypeTestCache& result = SubtypeTestCache::Handle(); | 7885 SubtypeTestCache& result = SubtypeTestCache::Handle(); |
7764 { | 7886 { |
7765 // SubtypeTestCache objects are long living objects, allocate them in the | 7887 // SubtypeTestCache objects are long living objects, allocate them in the |
7766 // old generation. | 7888 // old generation. |
7767 RawObject* raw = Object::Allocate(SubtypeTestCache::kClassId, | 7889 RawObject* raw = Object::Allocate(SubtypeTestCache::kClassId, |
7768 SubtypeTestCache::InstanceSize(), | 7890 SubtypeTestCache::InstanceSize(), |
7769 Heap::kOld); | 7891 Heap::kOld); |
7770 NoGCScope no_gc; | 7892 NoGCScope no_gc; |
(...skipping 4312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12083 } | 12205 } |
12084 return result.raw(); | 12206 return result.raw(); |
12085 } | 12207 } |
12086 | 12208 |
12087 | 12209 |
12088 const char* WeakProperty::ToCString() const { | 12210 const char* WeakProperty::ToCString() const { |
12089 return "_WeakProperty"; | 12211 return "_WeakProperty"; |
12090 } | 12212 } |
12091 | 12213 |
12092 } // namespace dart | 12214 } // namespace dart |
OLD | NEW |