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 |