Index: runtime/vm/megamorphic_cache_table.cc |
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..182d86017b4f0c134d5f625f7932def3b636ff6e |
--- /dev/null |
+++ b/runtime/vm/megamorphic_cache_table.cc |
@@ -0,0 +1,104 @@ |
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+#include "vm/megamorphic_cache_table.h" |
+ |
+#include <stdlib.h> |
+#include "vm/object.h" |
+#include "vm/stub_code.h" |
+#include "vm/symbols.h" |
+ |
+namespace dart { |
+ |
+MegamorphicCacheTable::MegamorphicCacheTable() |
+ : miss_handler_(NULL), |
+ capacity_(kInitialCapacity), |
+ length_(0), |
+ table_(NULL) { |
+} |
+ |
+ |
+MegamorphicCacheTable::~MegamorphicCacheTable() { |
+ free(table_); |
+} |
+ |
+ |
+RawMegamorphicCache* MegamorphicCacheTable::Lookup(const String& name, |
+ const Array& descriptor) { |
+ if (table_ == NULL) { |
+ table_ = |
+ reinterpret_cast<Entry*>(malloc(kInitialCapacity * sizeof(*table_))); |
+ } |
+ |
+ for (intptr_t i = 0; i < length_; ++i) { |
+ if ((table_[i].name == name.raw()) && |
+ (table_[i].descriptor == descriptor.raw())) { |
+ return table_[i].cache; |
+ } |
+ } |
+ |
+ if (length_ == capacity_) { |
+ capacity_ += kCapacityIncrement; |
+ table_ = |
+ reinterpret_cast<Entry*>(realloc(table_, capacity_ * sizeof(*table_))); |
+ } |
+ |
+ ASSERT(length_ < capacity_); |
+ const MegamorphicCache& cache = |
+ MegamorphicCache::Handle(MegamorphicCache::New()); |
+ Entry entry = { name.raw(), descriptor.raw(), cache.raw() }; |
+ table_[length_++] = entry; |
+ return cache.raw(); |
+} |
+ |
+ |
+void MegamorphicCacheTable::InitMissHandler() { |
+ // The miss handler for a class ID not found in the table is invoked as a |
+ // normal Dart function. |
+ const Code& code = |
+ Code::Handle(StubCode::Generate("_stub_MegamorphicMiss", |
+ StubCode::GenerateMegamorphicMissStub)); |
+ const String& name = String::Handle(Symbols::New("megamorphic_miss")); |
+ const Class& cls = |
+ Class::Handle(Type::Handle(Type::Function()).type_class()); |
+ const Function& function = |
+ Function::Handle(Function::New(name, |
+ RawFunction::kRegularFunction, |
+ false, // Not static. |
+ false, // Not const. |
+ false, // Not abstract. |
+ false, // Not external. |
+ cls, |
+ 0)); // No token position. |
+ function.SetCode(code); |
+ miss_handler_ = function.raw(); |
+} |
+ |
+ |
+void MegamorphicCacheTable::VisitObjectPointers(ObjectPointerVisitor* v) { |
+ ASSERT(v != NULL); |
+ v->VisitPointer(reinterpret_cast<RawObject**>(&miss_handler_)); |
+ for (intptr_t i = 0; i < length_; ++i) { |
+ v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].name)); |
+ v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].descriptor)); |
+ v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].cache)); |
+ } |
+} |
+ |
+ |
+void MegamorphicCacheTable::PrintSizes() { |
+ StackZone zone(Isolate::Current()); |
+ intptr_t size = 0; |
+ MegamorphicCache& cache = MegamorphicCache::Handle(); |
+ Array& buckets = Array::Handle(); |
+ for (intptr_t i = 0; i < length_; ++i) { |
+ cache = table_[i].cache; |
+ buckets = cache.buckets(); |
+ size += MegamorphicCache::InstanceSize(); |
+ size += Array::InstanceSize(buckets.Length()); |
+ } |
+ OS::Print("%"Pd" megamorphic caches using %"Pd"KB.\n", length_, size / 1024); |
+} |
+ |
+} // namespace dart |