Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: runtime/vm/object.cc

Issue 11299298: Cache lookups at megamorphic call sites in optimized code. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: One change I forgot. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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::filled_entry_count() const {
7791 return raw_ptr()->filled_entry_count_;
7792 }
7793
7794
7795 void MegamorphicCache::set_filled_entry_count(intptr_t count) const {
7796 raw_ptr()->filled_entry_count_ = 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 capacity = kInitialCapacity;
7809 const Array& buckets = Array::Handle(Array::New(kEntryLength * capacity));
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 < capacity; ++i) {
7814 SetEntry(buckets, i, illegal, handler);
7815 }
7816 result.set_buckets(buckets);
7817 result.set_mask(capacity - 1);
7818 result.set_filled_entry_count(0);
7819 return result.raw();
7820 }
7821
7822
7823 void MegamorphicCache::EnsureCapacity() const {
7824 intptr_t old_capacity = mask() + 1;
7825 double load_limit = kLoadFactor * static_cast<double>(old_capacity);
7826 if (static_cast<double>(filled_entry_count() + 1) > load_limit) {
7827 const Array& old_buckets = Array::Handle(buckets());
7828 intptr_t new_capacity = old_capacity * 2;
7829 const Array& new_buckets =
7830 Array::Handle(Array::New(kEntryLength * new_capacity));
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_capacity; ++i) {
7836 SetEntry(new_buckets, i, class_id, target);
7837 }
7838 set_buckets(new_buckets);
7839 set_mask(new_capacity - 1);
7840 set_filled_entry_count(0);
7841
7842 // Rehash the valid entries.
7843 for (intptr_t i = 0; i < old_capacity; ++i) {
7844 class_id ^= GetClassId(old_buckets, i);
7845 if (class_id.Value() != kIllegalCid) {
7846 target ^= GetTargetFunction(old_buckets, i);
7847 Insert(class_id, target);
7848 }
7849 }
7850 }
7851 }
7852
7853
7854 void MegamorphicCache::Insert(const Smi& class_id,
7855 const Function& target) const {
7856 ASSERT(static_cast<double>(filled_entry_count() + 1) <=
7857 (kLoadFactor * static_cast<double>(mask() + 1)));
7858 const Array& backing_array = Array::Handle(buckets());
7859 intptr_t id_mask = mask();
7860 intptr_t index = class_id.Value() & id_mask;
7861 Smi& probe = Smi::Handle();
7862 intptr_t i = index;
7863 do {
7864 probe ^= GetClassId(backing_array, i);
7865 if (probe.Value() == kIllegalCid) {
7866 SetEntry(backing_array, i, class_id, target);
7867 set_filled_entry_count(filled_entry_count() + 1);
7868 return;
7869 }
7870 i = (i + 1) & id_mask;
7871 } while (i != index);
7872 UNREACHABLE();
7873 }
7874
7875
7876 const char* MegamorphicCache::ToCString() const {
7877 return "";
7878 }
7879
7880
7761 RawSubtypeTestCache* SubtypeTestCache::New() { 7881 RawSubtypeTestCache* SubtypeTestCache::New() {
7762 ASSERT(Object::subtypetestcache_class() != Class::null()); 7882 ASSERT(Object::subtypetestcache_class() != Class::null());
7763 SubtypeTestCache& result = SubtypeTestCache::Handle(); 7883 SubtypeTestCache& result = SubtypeTestCache::Handle();
7764 { 7884 {
7765 // SubtypeTestCache objects are long living objects, allocate them in the 7885 // SubtypeTestCache objects are long living objects, allocate them in the
7766 // old generation. 7886 // old generation.
7767 RawObject* raw = Object::Allocate(SubtypeTestCache::kClassId, 7887 RawObject* raw = Object::Allocate(SubtypeTestCache::kClassId,
7768 SubtypeTestCache::InstanceSize(), 7888 SubtypeTestCache::InstanceSize(),
7769 Heap::kOld); 7889 Heap::kOld);
7770 NoGCScope no_gc; 7890 NoGCScope no_gc;
(...skipping 4344 matching lines...) Expand 10 before | Expand all | Expand 10 after
12115 } 12235 }
12116 return result.raw(); 12236 return result.raw();
12117 } 12237 }
12118 12238
12119 12239
12120 const char* WeakProperty::ToCString() const { 12240 const char* WeakProperty::ToCString() const {
12121 return "_WeakProperty"; 12241 return "_WeakProperty";
12122 } 12242 }
12123 12243
12124 } // namespace dart 12244 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698