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

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: 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
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::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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698