OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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/program_visitor.h" | 5 #include "vm/program_visitor.h" |
6 | 6 |
7 #include "vm/deopt_instructions.h" | 7 #include "vm/deopt_instructions.h" |
| 8 #include "vm/hash_map.h" |
8 #include "vm/object.h" | 9 #include "vm/object.h" |
9 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
10 #include "vm/hash_map.h" | |
11 #include "vm/symbols.h" | 11 #include "vm/symbols.h" |
12 | 12 |
13 namespace dart { | 13 namespace dart { |
14 | 14 |
15 void ProgramVisitor::VisitClasses(ClassVisitor* visitor) { | 15 void ProgramVisitor::VisitClasses(ClassVisitor* visitor) { |
16 Thread* thread = Thread::Current(); | 16 Thread* thread = Thread::Current(); |
17 Isolate* isolate = thread->isolate(); | 17 Isolate* isolate = thread->isolate(); |
18 Zone* zone = thread->zone(); | 18 Zone* zone = thread->zone(); |
19 GrowableObjectArray& libraries = | 19 GrowableObjectArray& libraries = |
20 GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); | 20 GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); |
21 Library& lib = Library::Handle(zone); | 21 Library& lib = Library::Handle(zone); |
22 Class& cls = Class::Handle(zone); | 22 Class& cls = Class::Handle(zone); |
23 | 23 |
24 for (intptr_t i = 0; i < libraries.Length(); i++) { | 24 for (intptr_t i = 0; i < libraries.Length(); i++) { |
25 lib ^= libraries.At(i); | 25 lib ^= libraries.At(i); |
26 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 26 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
27 while (it.HasNext()) { | 27 while (it.HasNext()) { |
28 cls = it.GetNextClass(); | 28 cls = it.GetNextClass(); |
29 if (cls.IsDynamicClass()) { | 29 if (cls.IsDynamicClass()) { |
30 continue; // class 'dynamic' is in the read-only VM isolate. | 30 continue; // class 'dynamic' is in the read-only VM isolate. |
31 } | 31 } |
32 visitor->Visit(cls); | 32 visitor->Visit(cls); |
33 } | 33 } |
34 } | 34 } |
35 } | 35 } |
36 | 36 |
37 | |
38 void ProgramVisitor::VisitFunctions(FunctionVisitor* visitor) { | 37 void ProgramVisitor::VisitFunctions(FunctionVisitor* visitor) { |
39 Thread* thread = Thread::Current(); | 38 Thread* thread = Thread::Current(); |
40 Isolate* isolate = thread->isolate(); | 39 Isolate* isolate = thread->isolate(); |
41 Zone* zone = thread->zone(); | 40 Zone* zone = thread->zone(); |
42 GrowableObjectArray& libraries = | 41 GrowableObjectArray& libraries = |
43 GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); | 42 GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); |
44 Library& lib = Library::Handle(zone); | 43 Library& lib = Library::Handle(zone); |
45 Class& cls = Class::Handle(zone); | 44 Class& cls = Class::Handle(zone); |
46 Array& functions = Array::Handle(zone); | 45 Array& functions = Array::Handle(zone); |
47 Array& fields = Array::Handle(zone); | 46 Array& fields = Array::Handle(zone); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 } | 87 } |
89 } | 88 } |
90 closures = isolate->object_store()->closure_functions(); | 89 closures = isolate->object_store()->closure_functions(); |
91 for (intptr_t j = 0; j < closures.Length(); j++) { | 90 for (intptr_t j = 0; j < closures.Length(); j++) { |
92 function ^= closures.At(j); | 91 function ^= closures.At(j); |
93 visitor->Visit(function); | 92 visitor->Visit(function); |
94 ASSERT(!function.HasImplicitClosureFunction()); | 93 ASSERT(!function.HasImplicitClosureFunction()); |
95 } | 94 } |
96 } | 95 } |
97 | 96 |
98 | |
99 void ProgramVisitor::ShareMegamorphicBuckets() { | 97 void ProgramVisitor::ShareMegamorphicBuckets() { |
100 Thread* thread = Thread::Current(); | 98 Thread* thread = Thread::Current(); |
101 Isolate* isolate = thread->isolate(); | 99 Isolate* isolate = thread->isolate(); |
102 Zone* zone = thread->zone(); | 100 Zone* zone = thread->zone(); |
103 | 101 |
104 const GrowableObjectArray& table = GrowableObjectArray::Handle( | 102 const GrowableObjectArray& table = GrowableObjectArray::Handle( |
105 zone, isolate->object_store()->megamorphic_cache_table()); | 103 zone, isolate->object_store()->megamorphic_cache_table()); |
106 if (table.IsNull()) return; | 104 if (table.IsNull()) return; |
107 MegamorphicCache& cache = MegamorphicCache::Handle(zone); | 105 MegamorphicCache& cache = MegamorphicCache::Handle(zone); |
108 | 106 |
109 const intptr_t capacity = 1; | 107 const intptr_t capacity = 1; |
110 const Array& buckets = Array::Handle( | 108 const Array& buckets = Array::Handle( |
111 zone, Array::New(MegamorphicCache::kEntryLength * capacity, Heap::kOld)); | 109 zone, Array::New(MegamorphicCache::kEntryLength * capacity, Heap::kOld)); |
112 const Function& handler = | 110 const Function& handler = |
113 Function::Handle(zone, MegamorphicCacheTable::miss_handler(isolate)); | 111 Function::Handle(zone, MegamorphicCacheTable::miss_handler(isolate)); |
114 MegamorphicCache::SetEntry(buckets, 0, MegamorphicCache::smi_illegal_cid(), | 112 MegamorphicCache::SetEntry(buckets, 0, MegamorphicCache::smi_illegal_cid(), |
115 handler); | 113 handler); |
116 | 114 |
117 for (intptr_t i = 0; i < table.Length(); i++) { | 115 for (intptr_t i = 0; i < table.Length(); i++) { |
118 cache ^= table.At(i); | 116 cache ^= table.At(i); |
119 cache.set_buckets(buckets); | 117 cache.set_buckets(buckets); |
120 cache.set_mask(capacity - 1); | 118 cache.set_mask(capacity - 1); |
121 cache.set_filled_entry_count(0); | 119 cache.set_filled_entry_count(0); |
122 } | 120 } |
123 } | 121 } |
124 | 122 |
125 | |
126 class StackMapKeyValueTrait { | 123 class StackMapKeyValueTrait { |
127 public: | 124 public: |
128 // Typedefs needed for the DirectChainedHashMap template. | 125 // Typedefs needed for the DirectChainedHashMap template. |
129 typedef const StackMap* Key; | 126 typedef const StackMap* Key; |
130 typedef const StackMap* Value; | 127 typedef const StackMap* Value; |
131 typedef const StackMap* Pair; | 128 typedef const StackMap* Pair; |
132 | 129 |
133 static Key KeyOf(Pair kv) { return kv; } | 130 static Key KeyOf(Pair kv) { return kv; } |
134 | 131 |
135 static Value ValueOf(Pair kv) { return kv; } | 132 static Value ValueOf(Pair kv) { return kv; } |
136 | 133 |
137 static inline intptr_t Hashcode(Key key) { return key->PcOffset(); } | 134 static inline intptr_t Hashcode(Key key) { return key->PcOffset(); } |
138 | 135 |
139 static inline bool IsKeyEqual(Pair pair, Key key) { | 136 static inline bool IsKeyEqual(Pair pair, Key key) { |
140 return pair->Equals(*key); | 137 return pair->Equals(*key); |
141 } | 138 } |
142 }; | 139 }; |
143 | 140 |
144 typedef DirectChainedHashMap<StackMapKeyValueTrait> StackMapSet; | 141 typedef DirectChainedHashMap<StackMapKeyValueTrait> StackMapSet; |
145 | 142 |
146 | |
147 void ProgramVisitor::DedupStackMaps() { | 143 void ProgramVisitor::DedupStackMaps() { |
148 class DedupStackMapsVisitor : public FunctionVisitor { | 144 class DedupStackMapsVisitor : public FunctionVisitor { |
149 public: | 145 public: |
150 explicit DedupStackMapsVisitor(Zone* zone) | 146 explicit DedupStackMapsVisitor(Zone* zone) |
151 : zone_(zone), | 147 : zone_(zone), |
152 canonical_stackmaps_(), | 148 canonical_stackmaps_(), |
153 code_(Code::Handle(zone)), | 149 code_(Code::Handle(zone)), |
154 stackmaps_(Array::Handle(zone)), | 150 stackmaps_(Array::Handle(zone)), |
155 stackmap_(StackMap::Handle(zone)) {} | 151 stackmap_(StackMap::Handle(zone)) {} |
156 | 152 |
(...skipping 28 matching lines...) Expand all Loading... |
185 StackMapSet canonical_stackmaps_; | 181 StackMapSet canonical_stackmaps_; |
186 Code& code_; | 182 Code& code_; |
187 Array& stackmaps_; | 183 Array& stackmaps_; |
188 StackMap& stackmap_; | 184 StackMap& stackmap_; |
189 }; | 185 }; |
190 | 186 |
191 DedupStackMapsVisitor visitor(Thread::Current()->zone()); | 187 DedupStackMapsVisitor visitor(Thread::Current()->zone()); |
192 ProgramVisitor::VisitFunctions(&visitor); | 188 ProgramVisitor::VisitFunctions(&visitor); |
193 } | 189 } |
194 | 190 |
195 | |
196 class PcDescriptorsKeyValueTrait { | 191 class PcDescriptorsKeyValueTrait { |
197 public: | 192 public: |
198 // Typedefs needed for the DirectChainedHashMap template. | 193 // Typedefs needed for the DirectChainedHashMap template. |
199 typedef const PcDescriptors* Key; | 194 typedef const PcDescriptors* Key; |
200 typedef const PcDescriptors* Value; | 195 typedef const PcDescriptors* Value; |
201 typedef const PcDescriptors* Pair; | 196 typedef const PcDescriptors* Pair; |
202 | 197 |
203 static Key KeyOf(Pair kv) { return kv; } | 198 static Key KeyOf(Pair kv) { return kv; } |
204 | 199 |
205 static Value ValueOf(Pair kv) { return kv; } | 200 static Value ValueOf(Pair kv) { return kv; } |
206 | 201 |
207 static inline intptr_t Hashcode(Key key) { return key->Length(); } | 202 static inline intptr_t Hashcode(Key key) { return key->Length(); } |
208 | 203 |
209 static inline bool IsKeyEqual(Pair pair, Key key) { | 204 static inline bool IsKeyEqual(Pair pair, Key key) { |
210 return pair->Equals(*key); | 205 return pair->Equals(*key); |
211 } | 206 } |
212 }; | 207 }; |
213 | 208 |
214 typedef DirectChainedHashMap<PcDescriptorsKeyValueTrait> PcDescriptorsSet; | 209 typedef DirectChainedHashMap<PcDescriptorsKeyValueTrait> PcDescriptorsSet; |
215 | 210 |
216 | |
217 void ProgramVisitor::DedupPcDescriptors() { | 211 void ProgramVisitor::DedupPcDescriptors() { |
218 class DedupPcDescriptorsVisitor : public FunctionVisitor { | 212 class DedupPcDescriptorsVisitor : public FunctionVisitor { |
219 public: | 213 public: |
220 explicit DedupPcDescriptorsVisitor(Zone* zone) | 214 explicit DedupPcDescriptorsVisitor(Zone* zone) |
221 : zone_(zone), | 215 : zone_(zone), |
222 canonical_pc_descriptors_(), | 216 canonical_pc_descriptors_(), |
223 code_(Code::Handle(zone)), | 217 code_(Code::Handle(zone)), |
224 pc_descriptor_(PcDescriptors::Handle(zone)) {} | 218 pc_descriptor_(PcDescriptors::Handle(zone)) {} |
225 | 219 |
226 void Visit(const Function& function) { | 220 void Visit(const Function& function) { |
(...skipping 23 matching lines...) Expand all Loading... |
250 Zone* zone_; | 244 Zone* zone_; |
251 PcDescriptorsSet canonical_pc_descriptors_; | 245 PcDescriptorsSet canonical_pc_descriptors_; |
252 Code& code_; | 246 Code& code_; |
253 PcDescriptors& pc_descriptor_; | 247 PcDescriptors& pc_descriptor_; |
254 }; | 248 }; |
255 | 249 |
256 DedupPcDescriptorsVisitor visitor(Thread::Current()->zone()); | 250 DedupPcDescriptorsVisitor visitor(Thread::Current()->zone()); |
257 ProgramVisitor::VisitFunctions(&visitor); | 251 ProgramVisitor::VisitFunctions(&visitor); |
258 } | 252 } |
259 | 253 |
260 | |
261 class TypedDataKeyValueTrait { | 254 class TypedDataKeyValueTrait { |
262 public: | 255 public: |
263 // Typedefs needed for the DirectChainedHashMap template. | 256 // Typedefs needed for the DirectChainedHashMap template. |
264 typedef const TypedData* Key; | 257 typedef const TypedData* Key; |
265 typedef const TypedData* Value; | 258 typedef const TypedData* Value; |
266 typedef const TypedData* Pair; | 259 typedef const TypedData* Pair; |
267 | 260 |
268 static Key KeyOf(Pair kv) { return kv; } | 261 static Key KeyOf(Pair kv) { return kv; } |
269 | 262 |
270 static Value ValueOf(Pair kv) { return kv; } | 263 static Value ValueOf(Pair kv) { return kv; } |
271 | 264 |
272 static inline intptr_t Hashcode(Key key) { | 265 static inline intptr_t Hashcode(Key key) { |
273 return key->ComputeCanonicalTableHash(); | 266 return key->ComputeCanonicalTableHash(); |
274 } | 267 } |
275 | 268 |
276 static inline bool IsKeyEqual(Pair pair, Key key) { | 269 static inline bool IsKeyEqual(Pair pair, Key key) { |
277 return pair->CanonicalizeEquals(*key); | 270 return pair->CanonicalizeEquals(*key); |
278 } | 271 } |
279 }; | 272 }; |
280 | 273 |
281 typedef DirectChainedHashMap<TypedDataKeyValueTrait> TypedDataSet; | 274 typedef DirectChainedHashMap<TypedDataKeyValueTrait> TypedDataSet; |
282 | 275 |
283 | |
284 #if !defined(DART_PRECOMPILED_RUNTIME) | 276 #if !defined(DART_PRECOMPILED_RUNTIME) |
285 void ProgramVisitor::DedupDeoptEntries() { | 277 void ProgramVisitor::DedupDeoptEntries() { |
286 class DedupDeoptEntriesVisitor : public FunctionVisitor { | 278 class DedupDeoptEntriesVisitor : public FunctionVisitor { |
287 public: | 279 public: |
288 explicit DedupDeoptEntriesVisitor(Zone* zone) | 280 explicit DedupDeoptEntriesVisitor(Zone* zone) |
289 : zone_(zone), | 281 : zone_(zone), |
290 canonical_deopt_entries_(), | 282 canonical_deopt_entries_(), |
291 code_(Code::Handle(zone)), | 283 code_(Code::Handle(zone)), |
292 deopt_table_(Array::Handle(zone)), | 284 deopt_table_(Array::Handle(zone)), |
293 deopt_entry_(TypedData::Handle(zone)), | 285 deopt_entry_(TypedData::Handle(zone)), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 TypedData& deopt_entry_; | 325 TypedData& deopt_entry_; |
334 Smi& offset_; | 326 Smi& offset_; |
335 Smi& reason_and_flags_; | 327 Smi& reason_and_flags_; |
336 }; | 328 }; |
337 | 329 |
338 DedupDeoptEntriesVisitor visitor(Thread::Current()->zone()); | 330 DedupDeoptEntriesVisitor visitor(Thread::Current()->zone()); |
339 ProgramVisitor::VisitFunctions(&visitor); | 331 ProgramVisitor::VisitFunctions(&visitor); |
340 } | 332 } |
341 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 333 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
342 | 334 |
343 | |
344 class CodeSourceMapKeyValueTrait { | 335 class CodeSourceMapKeyValueTrait { |
345 public: | 336 public: |
346 // Typedefs needed for the DirectChainedHashMap template. | 337 // Typedefs needed for the DirectChainedHashMap template. |
347 typedef const CodeSourceMap* Key; | 338 typedef const CodeSourceMap* Key; |
348 typedef const CodeSourceMap* Value; | 339 typedef const CodeSourceMap* Value; |
349 typedef const CodeSourceMap* Pair; | 340 typedef const CodeSourceMap* Pair; |
350 | 341 |
351 static Key KeyOf(Pair kv) { return kv; } | 342 static Key KeyOf(Pair kv) { return kv; } |
352 | 343 |
353 static Value ValueOf(Pair kv) { return kv; } | 344 static Value ValueOf(Pair kv) { return kv; } |
354 | 345 |
355 static inline intptr_t Hashcode(Key key) { return key->Length(); } | 346 static inline intptr_t Hashcode(Key key) { return key->Length(); } |
356 | 347 |
357 static inline bool IsKeyEqual(Pair pair, Key key) { | 348 static inline bool IsKeyEqual(Pair pair, Key key) { |
358 return pair->Equals(*key); | 349 return pair->Equals(*key); |
359 } | 350 } |
360 }; | 351 }; |
361 | 352 |
362 typedef DirectChainedHashMap<CodeSourceMapKeyValueTrait> CodeSourceMapSet; | 353 typedef DirectChainedHashMap<CodeSourceMapKeyValueTrait> CodeSourceMapSet; |
363 | 354 |
364 | |
365 void ProgramVisitor::DedupCodeSourceMaps() { | 355 void ProgramVisitor::DedupCodeSourceMaps() { |
366 class DedupCodeSourceMapsVisitor : public FunctionVisitor { | 356 class DedupCodeSourceMapsVisitor : public FunctionVisitor { |
367 public: | 357 public: |
368 explicit DedupCodeSourceMapsVisitor(Zone* zone) | 358 explicit DedupCodeSourceMapsVisitor(Zone* zone) |
369 : zone_(zone), | 359 : zone_(zone), |
370 canonical_code_source_maps_(), | 360 canonical_code_source_maps_(), |
371 code_(Code::Handle(zone)), | 361 code_(Code::Handle(zone)), |
372 code_source_map_(CodeSourceMap::Handle(zone)) {} | 362 code_source_map_(CodeSourceMap::Handle(zone)) {} |
373 | 363 |
374 void Visit(const Function& function) { | 364 void Visit(const Function& function) { |
(...skipping 23 matching lines...) Expand all Loading... |
398 Zone* zone_; | 388 Zone* zone_; |
399 CodeSourceMapSet canonical_code_source_maps_; | 389 CodeSourceMapSet canonical_code_source_maps_; |
400 Code& code_; | 390 Code& code_; |
401 CodeSourceMap& code_source_map_; | 391 CodeSourceMap& code_source_map_; |
402 }; | 392 }; |
403 | 393 |
404 DedupCodeSourceMapsVisitor visitor(Thread::Current()->zone()); | 394 DedupCodeSourceMapsVisitor visitor(Thread::Current()->zone()); |
405 ProgramVisitor::VisitFunctions(&visitor); | 395 ProgramVisitor::VisitFunctions(&visitor); |
406 } | 396 } |
407 | 397 |
408 | |
409 class ArrayKeyValueTrait { | 398 class ArrayKeyValueTrait { |
410 public: | 399 public: |
411 // Typedefs needed for the DirectChainedHashMap template. | 400 // Typedefs needed for the DirectChainedHashMap template. |
412 typedef const Array* Key; | 401 typedef const Array* Key; |
413 typedef const Array* Value; | 402 typedef const Array* Value; |
414 typedef const Array* Pair; | 403 typedef const Array* Pair; |
415 | 404 |
416 static Key KeyOf(Pair kv) { return kv; } | 405 static Key KeyOf(Pair kv) { return kv; } |
417 | 406 |
418 static Value ValueOf(Pair kv) { return kv; } | 407 static Value ValueOf(Pair kv) { return kv; } |
419 | 408 |
420 static inline intptr_t Hashcode(Key key) { return key->Length(); } | 409 static inline intptr_t Hashcode(Key key) { return key->Length(); } |
421 | 410 |
422 static inline bool IsKeyEqual(Pair pair, Key key) { | 411 static inline bool IsKeyEqual(Pair pair, Key key) { |
423 if (pair->Length() != key->Length()) { | 412 if (pair->Length() != key->Length()) { |
424 return false; | 413 return false; |
425 } | 414 } |
426 for (intptr_t i = 0; i < pair->Length(); i++) { | 415 for (intptr_t i = 0; i < pair->Length(); i++) { |
427 if (pair->At(i) != key->At(i)) { | 416 if (pair->At(i) != key->At(i)) { |
428 return false; | 417 return false; |
429 } | 418 } |
430 } | 419 } |
431 return true; | 420 return true; |
432 } | 421 } |
433 }; | 422 }; |
434 | 423 |
435 typedef DirectChainedHashMap<ArrayKeyValueTrait> ArraySet; | 424 typedef DirectChainedHashMap<ArrayKeyValueTrait> ArraySet; |
436 | 425 |
437 | |
438 void ProgramVisitor::DedupLists() { | 426 void ProgramVisitor::DedupLists() { |
439 class DedupListsVisitor : public FunctionVisitor { | 427 class DedupListsVisitor : public FunctionVisitor { |
440 public: | 428 public: |
441 explicit DedupListsVisitor(Zone* zone) | 429 explicit DedupListsVisitor(Zone* zone) |
442 : zone_(zone), | 430 : zone_(zone), |
443 canonical_lists_(), | 431 canonical_lists_(), |
444 code_(Code::Handle(zone)), | 432 code_(Code::Handle(zone)), |
445 list_(Array::Handle(zone)) {} | 433 list_(Array::Handle(zone)) {} |
446 | 434 |
447 void Visit(const Function& function) { | 435 void Visit(const Function& function) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 Zone* zone_; | 513 Zone* zone_; |
526 ArraySet canonical_lists_; | 514 ArraySet canonical_lists_; |
527 Code& code_; | 515 Code& code_; |
528 Array& list_; | 516 Array& list_; |
529 }; | 517 }; |
530 | 518 |
531 DedupListsVisitor visitor(Thread::Current()->zone()); | 519 DedupListsVisitor visitor(Thread::Current()->zone()); |
532 ProgramVisitor::VisitFunctions(&visitor); | 520 ProgramVisitor::VisitFunctions(&visitor); |
533 } | 521 } |
534 | 522 |
535 | |
536 class InstructionsKeyValueTrait { | 523 class InstructionsKeyValueTrait { |
537 public: | 524 public: |
538 // Typedefs needed for the DirectChainedHashMap template. | 525 // Typedefs needed for the DirectChainedHashMap template. |
539 typedef const Instructions* Key; | 526 typedef const Instructions* Key; |
540 typedef const Instructions* Value; | 527 typedef const Instructions* Value; |
541 typedef const Instructions* Pair; | 528 typedef const Instructions* Pair; |
542 | 529 |
543 static Key KeyOf(Pair kv) { return kv; } | 530 static Key KeyOf(Pair kv) { return kv; } |
544 | 531 |
545 static Value ValueOf(Pair kv) { return kv; } | 532 static Value ValueOf(Pair kv) { return kv; } |
546 | 533 |
547 static inline intptr_t Hashcode(Key key) { return key->Size(); } | 534 static inline intptr_t Hashcode(Key key) { return key->Size(); } |
548 | 535 |
549 static inline bool IsKeyEqual(Pair pair, Key key) { | 536 static inline bool IsKeyEqual(Pair pair, Key key) { |
550 return pair->Equals(*key); | 537 return pair->Equals(*key); |
551 } | 538 } |
552 }; | 539 }; |
553 | 540 |
554 typedef DirectChainedHashMap<InstructionsKeyValueTrait> InstructionsSet; | 541 typedef DirectChainedHashMap<InstructionsKeyValueTrait> InstructionsSet; |
555 | 542 |
556 | |
557 void ProgramVisitor::DedupInstructions() { | 543 void ProgramVisitor::DedupInstructions() { |
558 class DedupInstructionsVisitor : public FunctionVisitor { | 544 class DedupInstructionsVisitor : public FunctionVisitor { |
559 public: | 545 public: |
560 explicit DedupInstructionsVisitor(Zone* zone) | 546 explicit DedupInstructionsVisitor(Zone* zone) |
561 : zone_(zone), | 547 : zone_(zone), |
562 canonical_instructions_set_(), | 548 canonical_instructions_set_(), |
563 code_(Code::Handle(zone)), | 549 code_(Code::Handle(zone)), |
564 instructions_(Instructions::Handle(zone)) {} | 550 instructions_(Instructions::Handle(zone)) {} |
565 | 551 |
566 void Visit(const Function& function) { | 552 void Visit(const Function& function) { |
(...skipping 24 matching lines...) Expand all Loading... |
591 Zone* zone_; | 577 Zone* zone_; |
592 InstructionsSet canonical_instructions_set_; | 578 InstructionsSet canonical_instructions_set_; |
593 Code& code_; | 579 Code& code_; |
594 Instructions& instructions_; | 580 Instructions& instructions_; |
595 }; | 581 }; |
596 | 582 |
597 DedupInstructionsVisitor visitor(Thread::Current()->zone()); | 583 DedupInstructionsVisitor visitor(Thread::Current()->zone()); |
598 ProgramVisitor::VisitFunctions(&visitor); | 584 ProgramVisitor::VisitFunctions(&visitor); |
599 } | 585 } |
600 | 586 |
601 | |
602 void ProgramVisitor::Dedup() { | 587 void ProgramVisitor::Dedup() { |
603 Thread* thread = Thread::Current(); | 588 Thread* thread = Thread::Current(); |
604 StackZone stack_zone(thread); | 589 StackZone stack_zone(thread); |
605 HANDLESCOPE(thread); | 590 HANDLESCOPE(thread); |
606 | 591 |
607 // TODO(rmacnak): Bind static calls whose target has been compiled. Forward | 592 // TODO(rmacnak): Bind static calls whose target has been compiled. Forward |
608 // references to disabled code. | 593 // references to disabled code. |
609 ShareMegamorphicBuckets(); | 594 ShareMegamorphicBuckets(); |
610 DedupStackMaps(); | 595 DedupStackMaps(); |
611 DedupPcDescriptors(); | 596 DedupPcDescriptors(); |
612 NOT_IN_PRECOMPILED(DedupDeoptEntries()); | 597 NOT_IN_PRECOMPILED(DedupDeoptEntries()); |
613 DedupCodeSourceMaps(); | 598 DedupCodeSourceMaps(); |
614 DedupLists(); | 599 DedupLists(); |
615 | 600 |
616 if (!FLAG_profiler) { | 601 if (!FLAG_profiler) { |
617 // Reduces binary size but obfuscates profiler results. | 602 // Reduces binary size but obfuscates profiler results. |
618 DedupInstructions(); | 603 DedupInstructions(); |
619 } | 604 } |
620 } | 605 } |
621 | 606 |
622 } // namespace dart | 607 } // namespace dart |
OLD | NEW |