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 |