| 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/megamorphic_cache_table.h" | 5 #include "vm/megamorphic_cache_table.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include "vm/object.h" | 8 #include "vm/object.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 #include "vm/stub_code.h" | 10 #include "vm/stub_code.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 RawFunction* MegamorphicCacheTable::miss_handler(Isolate* isolate) { | 46 RawFunction* MegamorphicCacheTable::miss_handler(Isolate* isolate) { |
| 47 ASSERT(isolate->object_store()->megamorphic_miss_function() != | 47 ASSERT(isolate->object_store()->megamorphic_miss_function() != |
| 48 Function::null()); | 48 Function::null()); |
| 49 return isolate->object_store()->megamorphic_miss_function(); | 49 return isolate->object_store()->megamorphic_miss_function(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 | 52 |
| 53 void MegamorphicCacheTable::InitMissHandler(Isolate* isolate) { | 53 void MegamorphicCacheTable::InitMissHandler(Isolate* isolate) { |
| 54 // The miss handler for a class ID not found in the table is invoked as a | 54 // The miss handler for a class ID not found in the table is invoked as a |
| 55 // normal Dart function. | 55 // normal Dart function. |
| 56 const Code& code = | 56 const Code& code = Code::Handle(StubCode::Generate( |
| 57 Code::Handle(StubCode::Generate("_stub_MegamorphicMiss", | 57 "_stub_MegamorphicMiss", StubCode::GenerateMegamorphicMissStub)); |
| 58 StubCode::GenerateMegamorphicMissStub)); | |
| 59 // When FLAG_lazy_dispatchers=false, this stub can be on the stack during | 58 // When FLAG_lazy_dispatchers=false, this stub can be on the stack during |
| 60 // exceptions, but it has a corresponding function so IsStubCode is false and | 59 // exceptions, but it has a corresponding function so IsStubCode is false and |
| 61 // it is considered in the search for an exception handler. | 60 // it is considered in the search for an exception handler. |
| 62 code.set_exception_handlers(Object::empty_exception_handlers()); | 61 code.set_exception_handlers(Object::empty_exception_handlers()); |
| 63 const Class& cls = | 62 const Class& cls = |
| 64 Class::Handle(Type::Handle(Type::DartFunctionType()).type_class()); | 63 Class::Handle(Type::Handle(Type::DartFunctionType()).type_class()); |
| 65 const Function& function = | 64 const Function& function = Function::Handle( |
| 66 Function::Handle(Function::New(Symbols::MegamorphicMiss(), | 65 Function::New(Symbols::MegamorphicMiss(), RawFunction::kRegularFunction, |
| 67 RawFunction::kRegularFunction, | 66 true, // Static, but called as a method. |
| 68 true, // Static, but called as a method. | 67 false, // Not const. |
| 69 false, // Not const. | 68 false, // Not abstract. |
| 70 false, // Not abstract. | 69 false, // Not external. |
| 71 false, // Not external. | 70 false, // Not native. |
| 72 false, // Not native. | 71 cls, TokenPosition::kNoSource)); |
| 73 cls, | |
| 74 TokenPosition::kNoSource)); | |
| 75 function.set_result_type(Type::Handle(Type::DynamicType())); | 72 function.set_result_type(Type::Handle(Type::DynamicType())); |
| 76 function.set_is_debuggable(false); | 73 function.set_is_debuggable(false); |
| 77 function.set_is_visible(false); | 74 function.set_is_visible(false); |
| 78 function.AttachCode(code); // Has a single entry point, as a static function. | 75 function.AttachCode(code); // Has a single entry point, as a static function. |
| 79 // For inclusion in Snapshot::kAppWithJIT. | 76 // For inclusion in Snapshot::kAppWithJIT. |
| 80 function.set_unoptimized_code(code); | 77 function.set_unoptimized_code(code); |
| 81 | 78 |
| 82 isolate->object_store()->SetMegamorphicMissHandler(code, function); | 79 isolate->object_store()->SetMegamorphicMissHandler(code, function); |
| 83 } | 80 } |
| 84 | 81 |
| 85 | 82 |
| 86 void MegamorphicCacheTable::PrintSizes(Isolate* isolate) { | 83 void MegamorphicCacheTable::PrintSizes(Isolate* isolate) { |
| 87 StackZone zone(Thread::Current()); | 84 StackZone zone(Thread::Current()); |
| 88 intptr_t size = 0; | 85 intptr_t size = 0; |
| 89 MegamorphicCache& cache = MegamorphicCache::Handle(); | 86 MegamorphicCache& cache = MegamorphicCache::Handle(); |
| 90 Array& buckets = Array::Handle(); | 87 Array& buckets = Array::Handle(); |
| 91 const GrowableObjectArray& table = GrowableObjectArray::Handle( | 88 const GrowableObjectArray& table = GrowableObjectArray::Handle( |
| 92 isolate->object_store()->megamorphic_cache_table()); | 89 isolate->object_store()->megamorphic_cache_table()); |
| 93 if (table.IsNull()) return; | 90 if (table.IsNull()) return; |
| 94 intptr_t max_size = 0; | 91 intptr_t max_size = 0; |
| 95 for (intptr_t i = 0; i < table.Length(); i++) { | 92 for (intptr_t i = 0; i < table.Length(); i++) { |
| 96 cache ^= table.At(i); | 93 cache ^= table.At(i); |
| 97 buckets = cache.buckets(); | 94 buckets = cache.buckets(); |
| 98 size += MegamorphicCache::InstanceSize(); | 95 size += MegamorphicCache::InstanceSize(); |
| 99 size += Array::InstanceSize(buckets.Length()); | 96 size += Array::InstanceSize(buckets.Length()); |
| 100 if (buckets.Length() > max_size) { | 97 if (buckets.Length() > max_size) { |
| 101 max_size = buckets.Length(); | 98 max_size = buckets.Length(); |
| 102 } | 99 } |
| 103 } | 100 } |
| 104 OS::Print("%" Pd " megamorphic caches using %" Pd "KB.\n", | 101 OS::Print("%" Pd " megamorphic caches using %" Pd "KB.\n", table.Length(), |
| 105 table.Length(), size / 1024); | 102 size / 1024); |
| 106 | 103 |
| 107 intptr_t* probe_counts = new intptr_t[max_size]; | 104 intptr_t* probe_counts = new intptr_t[max_size]; |
| 108 intptr_t entry_count = 0; | 105 intptr_t entry_count = 0; |
| 109 intptr_t max_probe_count = 0; | 106 intptr_t max_probe_count = 0; |
| 110 for (intptr_t i = 0; i < max_size; i++) { | 107 for (intptr_t i = 0; i < max_size; i++) { |
| 111 probe_counts[i] = 0; | 108 probe_counts[i] = 0; |
| 112 } | 109 } |
| 113 for (intptr_t i = 0; i < table.Length(); i++) { | 110 for (intptr_t i = 0; i < table.Length(); i++) { |
| 114 cache ^= table.At(i); | 111 cache ^= table.At(i); |
| 115 buckets = cache.buckets(); | 112 buckets = cache.buckets(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 136 if (probe_count > max_probe_count) { | 133 if (probe_count > max_probe_count) { |
| 137 max_probe_count = probe_count; | 134 max_probe_count = probe_count; |
| 138 } | 135 } |
| 139 entry_count++; | 136 entry_count++; |
| 140 } | 137 } |
| 141 } | 138 } |
| 142 } | 139 } |
| 143 intptr_t cumulative_entries = 0; | 140 intptr_t cumulative_entries = 0; |
| 144 for (intptr_t i = 0; i <= max_probe_count; i++) { | 141 for (intptr_t i = 0; i <= max_probe_count; i++) { |
| 145 cumulative_entries += probe_counts[i]; | 142 cumulative_entries += probe_counts[i]; |
| 146 OS::Print("Megamorphic probe %" Pd ": %" Pd " (%lf)\n", | 143 OS::Print("Megamorphic probe %" Pd ": %" Pd " (%lf)\n", i, probe_counts[i], |
| 147 i, probe_counts[i], | |
| 148 static_cast<double>(cumulative_entries) / | 144 static_cast<double>(cumulative_entries) / |
| 149 static_cast<double>(entry_count)); | 145 static_cast<double>(entry_count)); |
| 150 } | 146 } |
| 151 delete[] probe_counts; | 147 delete[] probe_counts; |
| 152 } | 148 } |
| 153 | 149 |
| 154 } // namespace dart | 150 } // namespace dart |
| OLD | NEW |