| 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/object.h" | 8 #include "vm/object.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 #include "vm/hash_map.h" | 10 #include "vm/hash_map.h" |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 return true; | 429 return true; |
| 430 } | 430 } |
| 431 }; | 431 }; |
| 432 | 432 |
| 433 typedef DirectChainedHashMap<ArrayKeyValueTrait> ArraySet; | 433 typedef DirectChainedHashMap<ArrayKeyValueTrait> ArraySet; |
| 434 | 434 |
| 435 | 435 |
| 436 void ProgramVisitor::DedupLists() { | 436 void ProgramVisitor::DedupLists() { |
| 437 class DedupListsVisitor : public FunctionVisitor { | 437 class DedupListsVisitor : public FunctionVisitor { |
| 438 public: | 438 public: |
| 439 DedupListsVisitor(Isolate* isolate, Zone* zone) | 439 explicit DedupListsVisitor(Zone* zone) |
| 440 : isolate_(isolate), | 440 : zone_(zone), |
| 441 zone_(zone), | |
| 442 canonical_lists_(), | 441 canonical_lists_(), |
| 443 code_(Code::Handle(zone)), | 442 code_(Code::Handle(zone)), |
| 444 list_(Array::Handle(zone)) {} | 443 list_(Array::Handle(zone)) {} |
| 445 | 444 |
| 446 void Visit(const Function& function) { | 445 void Visit(const Function& function) { |
| 447 code_ = function.CurrentCode(); | 446 code_ = function.CurrentCode(); |
| 448 if (!code_.IsNull()) { | 447 if (!code_.IsNull()) { |
| 449 list_ = code_.stackmaps(); | 448 list_ = code_.stackmaps(); |
| 450 if (!list_.IsNull()) { | 449 if (!list_.IsNull()) { |
| 451 list_ = DedupList(list_); | 450 list_ = DedupList(list_); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 470 #endif // !PRODUCT | 469 #endif // !PRODUCT |
| 471 list_ = code_.static_calls_target_table(); | 470 list_ = code_.static_calls_target_table(); |
| 472 if (!list_.IsNull()) { | 471 if (!list_.IsNull()) { |
| 473 list_ = DedupList(list_); | 472 list_ = DedupList(list_); |
| 474 code_.set_static_calls_target_table(list_); | 473 code_.set_static_calls_target_table(list_); |
| 475 } | 474 } |
| 476 } | 475 } |
| 477 | 476 |
| 478 list_ = function.parameter_types(); | 477 list_ = function.parameter_types(); |
| 479 if (!list_.IsNull()) { | 478 if (!list_.IsNull()) { |
| 480 // Preserve parameter types in case of recompilation in JIT checked | 479 // Preserve parameter types in the JIT. Needed in case of recompilation |
| 481 // mode, or if available to mirrors. | 480 // in checked mode, or if available to mirrors, or for copied types to |
| 482 if (FLAG_precompiled_mode || | 481 // lazily generated tear offs. |
| 483 (!FLAG_enable_mirrors && !isolate_->type_checks())) { | 482 if (FLAG_precompiled_mode) { |
| 484 if (!function.IsSignatureFunction() && | 483 if (!function.IsSignatureFunction() && |
| 485 !function.IsClosureFunction() && | 484 !function.IsClosureFunction() && |
| 486 (function.name() != Symbols::Call().raw()) && !list_.InVMHeap()) { | 485 (function.name() != Symbols::Call().raw()) && !list_.InVMHeap()) { |
| 487 // Parameter types not needed for function type tests. | 486 // Parameter types not needed for function type tests. |
| 488 for (intptr_t i = 0; i < list_.Length(); i++) { | 487 for (intptr_t i = 0; i < list_.Length(); i++) { |
| 489 list_.SetAt(i, Object::dynamic_type()); | 488 list_.SetAt(i, Object::dynamic_type()); |
| 490 } | 489 } |
| 491 } | 490 } |
| 492 } | 491 } |
| 493 list_ = DedupList(list_); | 492 list_ = DedupList(list_); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 514 const Array* canonical_list = canonical_lists_.LookupValue(&list); | 513 const Array* canonical_list = canonical_lists_.LookupValue(&list); |
| 515 if (canonical_list == NULL) { | 514 if (canonical_list == NULL) { |
| 516 canonical_lists_.Insert(&Array::ZoneHandle(zone_, list.raw())); | 515 canonical_lists_.Insert(&Array::ZoneHandle(zone_, list.raw())); |
| 517 return list.raw(); | 516 return list.raw(); |
| 518 } else { | 517 } else { |
| 519 return canonical_list->raw(); | 518 return canonical_list->raw(); |
| 520 } | 519 } |
| 521 } | 520 } |
| 522 | 521 |
| 523 private: | 522 private: |
| 524 Isolate* isolate_; | |
| 525 Zone* zone_; | 523 Zone* zone_; |
| 526 ArraySet canonical_lists_; | 524 ArraySet canonical_lists_; |
| 527 Code& code_; | 525 Code& code_; |
| 528 Array& list_; | 526 Array& list_; |
| 529 }; | 527 }; |
| 530 | 528 |
| 531 Thread* thread = Thread::Current(); | 529 DedupListsVisitor visitor(Thread::Current()->zone()); |
| 532 DedupListsVisitor visitor(thread->isolate(), thread->zone()); | |
| 533 ProgramVisitor::VisitFunctions(&visitor); | 530 ProgramVisitor::VisitFunctions(&visitor); |
| 534 } | 531 } |
| 535 | 532 |
| 536 | 533 |
| 537 class InstructionsKeyValueTrait { | 534 class InstructionsKeyValueTrait { |
| 538 public: | 535 public: |
| 539 // Typedefs needed for the DirectChainedHashMap template. | 536 // Typedefs needed for the DirectChainedHashMap template. |
| 540 typedef const Instructions* Key; | 537 typedef const Instructions* Key; |
| 541 typedef const Instructions* Value; | 538 typedef const Instructions* Value; |
| 542 typedef const Instructions* Pair; | 539 typedef const Instructions* Pair; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 559 class DedupInstructionsVisitor : public FunctionVisitor { | 556 class DedupInstructionsVisitor : public FunctionVisitor { |
| 560 public: | 557 public: |
| 561 explicit DedupInstructionsVisitor(Zone* zone) | 558 explicit DedupInstructionsVisitor(Zone* zone) |
| 562 : zone_(zone), | 559 : zone_(zone), |
| 563 canonical_instructions_set_(), | 560 canonical_instructions_set_(), |
| 564 code_(Code::Handle(zone)), | 561 code_(Code::Handle(zone)), |
| 565 instructions_(Instructions::Handle(zone)) {} | 562 instructions_(Instructions::Handle(zone)) {} |
| 566 | 563 |
| 567 void Visit(const Function& function) { | 564 void Visit(const Function& function) { |
| 568 if (!function.HasCode()) { | 565 if (!function.HasCode()) { |
| 569 ASSERT(function.HasImplicitClosureFunction()); | |
| 570 return; | 566 return; |
| 571 } | 567 } |
| 572 code_ = function.CurrentCode(); | 568 code_ = function.CurrentCode(); |
| 573 instructions_ = code_.instructions(); | 569 instructions_ = code_.instructions(); |
| 574 instructions_ = DedupOneInstructions(instructions_); | 570 instructions_ = DedupOneInstructions(instructions_); |
| 575 code_.SetActiveInstructions(instructions_); | 571 code_.SetActiveInstructions(instructions_); |
| 576 code_.set_instructions(instructions_); | 572 code_.set_instructions(instructions_); |
| 577 function.SetInstructions(code_); // Update cached entry point. | 573 function.SetInstructions(code_); // Update cached entry point. |
| 578 } | 574 } |
| 579 | 575 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 DedupCodeSourceMaps(); | 611 DedupCodeSourceMaps(); |
| 616 DedupLists(); | 612 DedupLists(); |
| 617 | 613 |
| 618 if (!FLAG_profiler) { | 614 if (!FLAG_profiler) { |
| 619 // Reduces binary size but obfuscates profiler results. | 615 // Reduces binary size but obfuscates profiler results. |
| 620 DedupInstructions(); | 616 DedupInstructions(); |
| 621 } | 617 } |
| 622 } | 618 } |
| 623 | 619 |
| 624 } // namespace dart | 620 } // namespace dart |
| OLD | NEW |