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/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 |