OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #include "vm/megamorphic_cache_table.h" | |
6 | |
7 #include <stdlib.h> | |
8 #include "vm/object.h" | |
9 #include "vm/stub_code.h" | |
10 #include "vm/symbols.h" | |
11 | |
12 namespace dart { | |
13 | |
14 MegamorphicCacheTable::MegamorphicCacheTable() | |
15 : miss_handler_(NULL), | |
16 capacity_(kInitialCapacity), | |
17 length_(0), | |
18 table_(NULL) { | |
19 } | |
20 | |
21 | |
22 MegamorphicCacheTable::~MegamorphicCacheTable() { | |
23 free(table_); | |
24 } | |
25 | |
26 | |
27 RawMegamorphicCache* MegamorphicCacheTable::Lookup(const String& name, | |
28 const Array& descriptor) { | |
29 if (table_ == NULL) { | |
30 table_ = | |
Vyacheslav Egorov (Google)
2012/12/10 09:23:44
If you make kInitialCapacity == kCapacityIncrement
Kevin Millikin (Google)
2012/12/10 09:30:46
Thanks. That's better.
| |
31 reinterpret_cast<Entry*>(malloc(kInitialCapacity * sizeof(*table_))); | |
32 } | |
33 | |
34 for (intptr_t i = 0; i < length_; ++i) { | |
35 if ((table_[i].name == name.raw()) && | |
36 (table_[i].descriptor == descriptor.raw())) { | |
37 return table_[i].cache; | |
38 } | |
39 } | |
40 | |
41 if (length_ == capacity_) { | |
42 capacity_ += kCapacityIncrement; | |
43 table_ = | |
44 reinterpret_cast<Entry*>(realloc(table_, capacity_ * sizeof(*table_))); | |
45 } | |
46 | |
47 ASSERT(length_ < capacity_); | |
48 const MegamorphicCache& cache = | |
49 MegamorphicCache::Handle(MegamorphicCache::New()); | |
50 Entry entry = { name.raw(), descriptor.raw(), cache.raw() }; | |
51 table_[length_++] = entry; | |
52 return cache.raw(); | |
53 } | |
54 | |
55 | |
56 void MegamorphicCacheTable::InitMissHandler() { | |
57 // The miss handler for a class ID not found in the table is invoked as a | |
58 // normal Dart function. | |
59 const Code& code = | |
60 Code::Handle(StubCode::Generate("_stub_MegamorphicMiss", | |
61 StubCode::GenerateMegamorphicMissStub)); | |
62 const String& name = String::Handle(Symbols::New("megamorphic_miss")); | |
63 const Class& cls = | |
64 Class::Handle(Type::Handle(Type::Function()).type_class()); | |
65 const Function& function = | |
66 Function::Handle(Function::New(name, | |
67 RawFunction::kRegularFunction, | |
68 false, // Not static. | |
69 false, // Not const. | |
70 false, // Not abstract. | |
71 false, // Not external. | |
72 cls, | |
73 0)); // No token position. | |
74 function.SetCode(code); | |
75 miss_handler_ = function.raw(); | |
76 } | |
77 | |
78 | |
79 void MegamorphicCacheTable::VisitObjectPointers(ObjectPointerVisitor* v) { | |
80 ASSERT(v != NULL); | |
81 v->VisitPointer(reinterpret_cast<RawObject**>(&miss_handler_)); | |
82 for (intptr_t i = 0; i < length_; ++i) { | |
83 v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].name)); | |
84 v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].descriptor)); | |
85 v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].cache)); | |
86 } | |
87 } | |
88 | |
89 | |
90 void MegamorphicCacheTable::PrintSizes() { | |
91 StackZone zone(Isolate::Current()); | |
92 intptr_t size = 0; | |
93 MegamorphicCache& cache = MegamorphicCache::Handle(); | |
94 Array& buckets = Array::Handle(); | |
95 for (intptr_t i = 0; i < length_; ++i) { | |
96 cache = table_[i].cache; | |
97 buckets = cache.buckets(); | |
98 size += MegamorphicCache::InstanceSize(); | |
99 size += Array::InstanceSize(buckets.Length()); | |
100 } | |
101 OS::Print("%"Pd" megamorphic caches using %"Pd"KB.\n", length_, size / 1024); | |
102 } | |
103 | |
104 } // namespace dart | |
OLD | NEW |