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

Side by Side Diff: vm/code_index_table.cc

Issue 10082017: Remove code index table. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 8 months 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
(Empty)
1 // Copyright (c) 2011, 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/code_index_table.h"
6
7 #include "vm/isolate.h"
8 #include "vm/object.h"
9 #include "vm/pages.h"
10 #include "vm/raw_object.h"
11 #include "vm/visitor.h"
12
13 namespace dart {
14
15 CodeIndexTable::CodeIndexTable() : code_pages_(NULL),
16 code_lists_(Array::null()),
17 largecode_pc_ranges_(NULL),
18 largecode_list_(Array::null()) {
19 code_pages_ = new IndexArray<CodePageInfo>(kInitialSize);
20 ASSERT(code_pages_ != NULL);
21 code_lists_ = Array::New(kInitialSize);
22 }
23
24
25 CodeIndexTable::~CodeIndexTable() {
26 for (intptr_t i = 0; i < code_pages_->length(); i++) {
27 IndexArray<PcRange>* pc_ranges = code_pages_->At(i).pc_ranges;
28 delete pc_ranges;
29 }
30 delete code_pages_;
31 code_lists_ = Array::null();
32 delete largecode_pc_ranges_;
33 largecode_list_ = Array::null();
34 }
35
36
37 void CodeIndexTable::AddCode(const Code& code) {
38 ASSERT(!code.IsNull());
39 uword entrypoint = code.EntryPoint(); // Entry point for a function.
40 intptr_t instr_size = code.Size(); // Instructions size for the function.
41 if (PageSpace::IsPageAllocatableSize(instr_size)) {
42 uword page_start = (entrypoint & ~(PageSpace::kPageSize - 1));
43 int page_index = FindPageIndex(page_start);
44 if (page_index == -1) {
45 // We do not have an entry for this code page, add one.
46 page_index = AddPageIndex(page_start);
47 }
48 ASSERT(page_index != -1);
49 // Add the entrypoint, size and function object at the specified index.
50 AddCodeToList(page_index, entrypoint, instr_size, code);
51 } else {
52 AddLargeCode(entrypoint, instr_size, code);
53 }
54 }
55
56
57 RawCode* CodeIndexTable::LookupCode(uword pc) const {
58 uword page_start = (pc & ~(PageSpace::kPageSize - 1));
59 int page_index = FindPageIndex(page_start);
60 if (page_index == -1) {
61 // Check if the pc exists in the large pc ranges as this might be
62 // the pc of a large code object. This would return the large code
63 // or a null object if it doesn't exist in that list too.
64 return LookupLargeCode(pc);
65 }
66 IndexArray<PcRange>* pc_ranges = code_pages_->At(page_index).pc_ranges;
67 const Array& codes_list = Array::Handle(code_lists_);
68 ASSERT(!codes_list.IsNull());
69 ASSERT(page_index < (codes_list.Length() - 1));
70 Array& codes = Array::Handle();
71 codes ^= codes_list.At(page_index);
72 return LookupCodeFromList(pc_ranges, codes, pc, kIsSorted);
73 }
74
75
76 void CodeIndexTable::VisitObjectPointers(ObjectPointerVisitor* visitor) {
77 ASSERT(visitor != NULL);
78 visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_lists_));
79 visitor->VisitPointer(reinterpret_cast<RawObject**>(&largecode_list_));
80 }
81
82
83 void CodeIndexTable::Init(Isolate* isolate) {
84 ASSERT(isolate->code_index_table() == NULL);
85 CodeIndexTable* code_index_table = new CodeIndexTable();
86 isolate->set_code_index_table(code_index_table);
87 }
88
89
90 int CodeIndexTable::AddPageIndex(uword page_start) {
91 ASSERT(FindPageIndex(page_start) == -1);
92 int page_index = code_pages_->length();
93 CodePageInfo code;
94 code.page_start = page_start;
95 code.pc_ranges = new IndexArray<PcRange>(kInitialSize);
96 ASSERT(code.pc_ranges != NULL);
97 code_pages_->Add(code); // code gets added at 'index'.
98 const Array& codes_list = Array::Handle(code_lists_);
99 ASSERT(!codes_list.IsNull());
100 const Array& codes = Array::Handle(Array::New(kInitialSize));
101 codes_list.SetAt(page_index, codes);
102 if (code_pages_->IsFull()) {
103 // Grow the index table.
104 int new_size = code_pages_->length() + kInitialSize;
105 GrowCodeIndexTable(new_size);
106 }
107 return page_index;
108 }
109
110
111 int CodeIndexTable::FindPageIndex(uword page_start) const {
112 // We don't expect too many code pages (maybe max of 16) so it is
113 // ok to scan linearly in order to find the page_start in this index
114 // table.
115 for (int i = 0; i < code_pages_->length(); i++) {
116 if (code_pages_->At(i).page_start == page_start) {
117 return i;
118 }
119 }
120 return -1;
121 }
122
123
124 void CodeIndexTable::AddCodeToList(int page_index,
125 uword entrypoint,
126 intptr_t size,
127 const Code& code) {
128 // Get PC ranges index array at specified index.
129 IndexArray<PcRange>* pc_ranges = code_pages_->At(page_index).pc_ranges;
130 ASSERT(pc_ranges != NULL);
131 const Array& codes_list = Array::Handle(code_lists_);
132 ASSERT(!codes_list.IsNull());
133 // Get functions array present at specified index.
134 Array& codes = Array::Handle();
135 codes ^= codes_list.At(page_index);
136 ASSERT(!codes.IsNull());
137 // Asserting with an unsorted search, to ensure addition of pc was done right.
138 ASSERT(FindPcIndex(*pc_ranges, entrypoint, kIsNotSorted) == -1);
139 AddCodeHelper(pc_ranges, codes, entrypoint, size, code);
140 if (pc_ranges->IsFull()) {
141 // Grow the pc ranges table and the associated functions table.
142 int new_size = pc_ranges->length() + kInitialSize;
143 pc_ranges->Resize(new_size);
144 codes = Array::Grow(codes, new_size);
145 codes_list.SetAt(page_index, codes);
146 }
147 }
148
149
150 void CodeIndexTable::AddLargeCode(uword entrypoint,
151 intptr_t size,
152 const Code& code) {
153 if (largecode_pc_ranges_ == NULL) {
154 // No large functions seen so far.
155 largecode_pc_ranges_ = new IndexArray<PcRange>(kInitialSize);
156 ASSERT(largecode_pc_ranges_ != NULL);
157 largecode_list_ = Array::New(kInitialSize);
158 }
159 ASSERT(FindPcIndex(*largecode_pc_ranges_, entrypoint, kIsNotSorted) == -1);
160 const Array& largecode_list = Array::Handle(largecode_list_);
161 ASSERT(!largecode_list.IsNull());
162 AddCodeHelper(largecode_pc_ranges_, largecode_list, entrypoint, size, code);
163 if (largecode_pc_ranges_->IsFull()) {
164 // Grow largecode_pc_ranges_ and largecode_list_.
165 int new_size = largecode_pc_ranges_->length() + kInitialSize;
166 largecode_pc_ranges_->Resize(new_size);
167 largecode_list_ = Array::Grow(largecode_list, new_size);
168 }
169 }
170
171
172 void CodeIndexTable::AddCodeHelper(IndexArray<PcRange>* pc_ranges,
173 const Array& codes,
174 uword entrypoint,
175 intptr_t size,
176 const Code& code) {
177 PcRange pc_range;
178 pc_range.entrypoint = entrypoint;
179 pc_range.size = size;
180 intptr_t next_slot = pc_ranges->length();
181 pc_ranges->Add(pc_range); // pc_range gets added at 'next_slot'.
182 codes.SetAt(next_slot, code);
183 }
184
185
186 RawCode* CodeIndexTable::LookupLargeCode(uword pc) const {
187 const Array& large_codes = Array::Handle(largecode_list_);
188 return LookupCodeFromList(largecode_pc_ranges_,
189 large_codes,
190 pc,
191 kIsNotSorted);
192 }
193
194
195 RawCode* CodeIndexTable::LookupCodeFromList(
196 IndexArray<PcRange>* pc_ranges,
197 const Array& codes,
198 uword pc,
199 bool sorted) {
200 if (pc_ranges == NULL) {
201 return Code::null(); // no entries in array so return null object.
202 }
203 intptr_t i = FindPcIndex(*pc_ranges, pc, sorted);
204 if (i == -1) {
205 return Code::null(); // no entry for pc, return null object.
206 }
207 // 'i' is in the index which holds the entry for the function,
208 // access the functions array at 'i' and return the function object.
209 ASSERT(!codes.IsNull());
210 ASSERT(i < (codes.Length() - 1));
211 Code& code = Code::Handle();
212 code ^= codes.At(i);
213 return code.raw();
214 }
215
216
217 intptr_t CodeIndexTable::FindPcIndex(const IndexArray<PcRange>& pc_ranges,
218 uword pc,
219 bool sorted) {
220 if (sorted) {
221 // The pc range entries are sorted, do a binary search to see if pc exists.
222 intptr_t low = 0;
223 intptr_t high = pc_ranges.length();
224 while (low < high) {
225 intptr_t mid = low + (high - low) / 2;
226 uword entrypoint = pc_ranges.At(mid).entrypoint;
227 intptr_t size = pc_ranges.At(mid).size;
228 if (entrypoint <= pc) {
229 if (pc < (entrypoint + size)) {
230 return mid; // Found entry, return index.
231 } else {
232 low = mid + 1;
233 }
234 } else {
235 high = mid;
236 }
237 }
238 } else {
239 // The pc range entries are not sorted, do a linear search.
240 for (intptr_t i = (pc_ranges.length() - 1); i >= 0; i--) {
241 uword entrypoint = pc_ranges.At(i).entrypoint;
242 intptr_t size = pc_ranges.At(i).size;
243 if (entrypoint <= pc && pc < (entrypoint + size)) {
244 return i; // Found entry, return index.
245 }
246 }
247 }
248 return -1; // Entry not found.
249 }
250
251
252 void CodeIndexTable::GrowCodeIndexTable(int new_size) {
253 code_pages_->Resize(new_size);
254 code_lists_ = Array::Grow(Array::Handle(code_lists_), new_size);
255 }
256
257 } // namespace dart
OLDNEW
« no previous file with comments | « vm/code_index_table.h ('k') | vm/code_index_table_test.cc » ('j') | vm/find_code_object_test.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698