OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 if (!pointer->is_set()) { | 596 if (!pointer->is_set()) { |
597 HConstant* constant = | 597 HConstant* constant = |
598 new(zone()) HConstant(value, Representation::Integer32()); | 598 new(zone()) HConstant(value, Representation::Integer32()); |
599 constant->InsertAfter(GetConstantUndefined()); | 599 constant->InsertAfter(GetConstantUndefined()); |
600 pointer->set(constant); | 600 pointer->set(constant); |
601 } | 601 } |
602 return pointer->get(); | 602 return pointer->get(); |
603 } | 603 } |
604 | 604 |
605 | 605 |
| 606 HConstant* HGraph::GetConstantSmi(SetOncePointer<HConstant>* pointer, |
| 607 int32_t value) { |
| 608 if (!pointer->is_set()) { |
| 609 HConstant* constant = |
| 610 new(zone()) HConstant(Handle<Object>(Smi::FromInt(value), isolate()), |
| 611 Representation::Tagged()); |
| 612 constant->InsertAfter(GetConstantUndefined()); |
| 613 pointer->set(constant); |
| 614 } |
| 615 return pointer->get(); |
| 616 } |
| 617 |
| 618 |
606 HConstant* HGraph::GetConstant0() { | 619 HConstant* HGraph::GetConstant0() { |
607 return GetConstantInt32(&constant_0_, 0); | 620 return GetConstantInt32(&constant_0_, 0); |
608 } | 621 } |
609 | 622 |
610 | 623 |
611 HConstant* HGraph::GetConstant1() { | 624 HConstant* HGraph::GetConstant1() { |
612 return GetConstantInt32(&constant_1_, 1); | 625 return GetConstantInt32(&constant_1_, 1); |
613 } | 626 } |
614 | 627 |
615 | 628 |
(...skipping 15 matching lines...) Expand all Loading... |
631 constant->InsertAfter(GetConstantUndefined()); \ | 644 constant->InsertAfter(GetConstantUndefined()); \ |
632 constant_##name##_.set(constant); \ | 645 constant_##name##_.set(constant); \ |
633 } \ | 646 } \ |
634 return constant_##name##_.get(); \ | 647 return constant_##name##_.get(); \ |
635 } | 648 } |
636 | 649 |
637 | 650 |
638 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) | 651 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) |
639 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) | 652 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) |
640 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) | 653 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) |
| 654 DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false) |
| 655 |
| 656 |
| 657 HConstant* HGraph::GetConstantSmi0() { |
| 658 return GetConstantSmi(&constant_smi_0_, 0); |
| 659 } |
| 660 |
| 661 |
| 662 HConstant* HGraph::GetConstantSmi1() { |
| 663 return GetConstantSmi(&constant_smi_1_, 1); |
| 664 } |
| 665 |
641 | 666 |
642 #undef DEFINE_GET_CONSTANT | 667 #undef DEFINE_GET_CONSTANT |
643 | 668 |
644 | 669 |
645 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder) | 670 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder) |
646 : builder_(builder), | 671 : builder_(builder), |
647 finished_(false) { | 672 finished_(false) { |
648 HEnvironment* env = builder->environment(); | 673 HEnvironment* env = builder->environment(); |
649 failure_block_ = builder->CreateBasicBlock(env->Copy()); | 674 failure_block_ = builder->CreateBasicBlock(env->Copy()); |
650 merge_block_ = builder->CreateBasicBlock(env->Copy()); | 675 merge_block_ = builder->CreateBasicBlock(env->Copy()); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 } | 849 } |
825 | 850 |
826 | 851 |
827 void HGraphBuilder::IfBuilder::CaptureContinuation( | 852 void HGraphBuilder::IfBuilder::CaptureContinuation( |
828 HIfContinuation* continuation) { | 853 HIfContinuation* continuation) { |
829 ASSERT(!finished_); | 854 ASSERT(!finished_); |
830 ASSERT(!captured_); | 855 ASSERT(!captured_); |
831 HBasicBlock* true_block = last_true_block_ == NULL | 856 HBasicBlock* true_block = last_true_block_ == NULL |
832 ? first_true_block_ | 857 ? first_true_block_ |
833 : last_true_block_; | 858 : last_true_block_; |
834 HBasicBlock* false_block = | 859 HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL) |
835 did_else_ ? builder_->current_block() : first_false_block_; | 860 ? builder_->current_block() |
| 861 : first_false_block_; |
836 continuation->Capture(true_block, false_block, position_); | 862 continuation->Capture(true_block, false_block, position_); |
837 captured_ = true; | 863 captured_ = true; |
838 End(); | 864 End(); |
839 } | 865 } |
840 | 866 |
841 | 867 |
842 void HGraphBuilder::IfBuilder::Then() { | 868 void HGraphBuilder::IfBuilder::Then() { |
843 ASSERT(!captured_); | 869 ASSERT(!captured_); |
844 ASSERT(!finished_); | 870 ASSERT(!finished_); |
845 did_then_ = true; | 871 did_then_ = true; |
(...skipping 12 matching lines...) Expand all Loading... |
858 ASSERT(!captured_); | 884 ASSERT(!captured_); |
859 ASSERT(!finished_); | 885 ASSERT(!finished_); |
860 last_true_block_ = builder_->current_block(); | 886 last_true_block_ = builder_->current_block(); |
861 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); | 887 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); |
862 builder_->set_current_block(first_false_block_); | 888 builder_->set_current_block(first_false_block_); |
863 did_else_ = true; | 889 did_else_ = true; |
864 } | 890 } |
865 | 891 |
866 | 892 |
867 void HGraphBuilder::IfBuilder::Deopt() { | 893 void HGraphBuilder::IfBuilder::Deopt() { |
868 ASSERT(!(did_then_ ^ did_else_)); | |
869 HBasicBlock* block = builder_->current_block(); | 894 HBasicBlock* block = builder_->current_block(); |
870 block->FinishExitWithDeoptimization(HDeoptimize::kUseAll); | 895 block->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
871 if (did_else_) { | 896 if (did_else_) { |
872 first_false_block_ = NULL; | 897 first_false_block_ = NULL; |
873 } else { | 898 } else { |
874 first_true_block_ = NULL; | 899 first_true_block_ = NULL; |
875 } | 900 } |
876 } | 901 } |
877 | 902 |
878 | 903 |
| 904 void HGraphBuilder::IfBuilder::Return(HValue* value) { |
| 905 HBasicBlock* block = builder_->current_block(); |
| 906 block->Finish(new(zone()) HReturn(value, |
| 907 builder_->environment()->LookupContext(), |
| 908 builder_->graph()->GetConstantMinus1())); |
| 909 if (did_else_) { |
| 910 first_false_block_ = NULL; |
| 911 } else { |
| 912 first_true_block_ = NULL; |
| 913 } |
| 914 } |
| 915 |
| 916 |
879 void HGraphBuilder::IfBuilder::End() { | 917 void HGraphBuilder::IfBuilder::End() { |
880 if (!captured_) { | 918 if (!captured_) { |
881 ASSERT(did_then_); | 919 ASSERT(did_then_); |
882 if (!did_else_) { | 920 if (!did_else_) { |
883 last_true_block_ = builder_->current_block(); | 921 last_true_block_ = builder_->current_block(); |
884 } | 922 } |
885 if (first_true_block_ == NULL) { | 923 if (first_true_block_ == NULL) { |
886 // Deopt on true. Nothing to do, just continue the false block. | 924 // Deopt on true. Nothing to do, just continue the false block. |
887 } else if (first_false_block_ == NULL) { | 925 } else if (first_false_block_ == NULL) { |
888 // Deopt on false. Nothing to do except switching to the true block. | 926 // Deopt on false. Nothing to do except switching to the true block. |
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1725 key_constant, | 1763 key_constant, |
1726 value, | 1764 value, |
1727 kind)); | 1765 kind)); |
1728 } | 1766 } |
1729 } | 1767 } |
1730 | 1768 |
1731 return object; | 1769 return object; |
1732 } | 1770 } |
1733 | 1771 |
1734 | 1772 |
| 1773 void HGraphBuilder::BuildCompareNil( |
| 1774 HValue* value, |
| 1775 EqualityKind kind, |
| 1776 CompareNilICStub::Types types, |
| 1777 Handle<Map> map, |
| 1778 int position, |
| 1779 HIfContinuation* continuation) { |
| 1780 IfBuilder if_nil(this, position); |
| 1781 bool needs_or = false; |
| 1782 if ((types & CompareNilICStub::kCompareAgainstNull) != 0) { |
| 1783 if (needs_or) if_nil.Or(); |
| 1784 if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull()); |
| 1785 needs_or = true; |
| 1786 } |
| 1787 if ((types & CompareNilICStub::kCompareAgainstUndefined) != 0) { |
| 1788 if (needs_or) if_nil.Or(); |
| 1789 if_nil.If<HCompareObjectEqAndBranch>(value, |
| 1790 graph()->GetConstantUndefined()); |
| 1791 needs_or = true; |
| 1792 } |
| 1793 // Handle either undetectable or monomorphic, not both. |
| 1794 ASSERT(((types & CompareNilICStub::kCompareAgainstUndetectable) == 0) || |
| 1795 ((types & CompareNilICStub::kCompareAgainstMonomorphicMap) == 0)); |
| 1796 if ((types & CompareNilICStub::kCompareAgainstUndetectable) != 0) { |
| 1797 if (needs_or) if_nil.Or(); |
| 1798 if_nil.If<HIsUndetectableAndBranch>(value); |
| 1799 } else { |
| 1800 if_nil.Then(); |
| 1801 if_nil.Else(); |
| 1802 if ((types & CompareNilICStub::kCompareAgainstMonomorphicMap) != 0) { |
| 1803 BuildCheckNonSmi(value); |
| 1804 // For ICs, the map checked below is a sentinel map that gets replaced by |
| 1805 // the monomorphic map when the code is used as a template to generate a |
| 1806 // new IC. For optimized functions, there is no sentinel map, the map |
| 1807 // emitted below is the actual monomorphic map. |
| 1808 BuildCheckMap(value, map); |
| 1809 } else { |
| 1810 if (kind == kNonStrictEquality) { |
| 1811 if_nil.Deopt(); |
| 1812 } |
| 1813 } |
| 1814 } |
| 1815 |
| 1816 if_nil.CaptureContinuation(continuation); |
| 1817 } |
| 1818 |
| 1819 |
1735 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1820 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
1736 TypeFeedbackOracle* oracle) | 1821 TypeFeedbackOracle* oracle) |
1737 : HGraphBuilder(info), | 1822 : HGraphBuilder(info), |
1738 function_state_(NULL), | 1823 function_state_(NULL), |
1739 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1824 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
1740 ast_context_(NULL), | 1825 ast_context_(NULL), |
1741 break_scope_(NULL), | 1826 break_scope_(NULL), |
1742 inlined_count_(0), | 1827 inlined_count_(0), |
1743 globals_(10, info->zone()), | 1828 globals_(10, info->zone()), |
1744 inline_bailout_(false) { | 1829 inline_bailout_(false) { |
(...skipping 8522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10267 | 10352 |
10268 | 10353 |
10269 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 10354 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
10270 HValue* value, | 10355 HValue* value, |
10271 NilValue nil) { | 10356 NilValue nil) { |
10272 ASSERT(!HasStackOverflow()); | 10357 ASSERT(!HasStackOverflow()); |
10273 ASSERT(current_block() != NULL); | 10358 ASSERT(current_block() != NULL); |
10274 ASSERT(current_block()->HasPredecessor()); | 10359 ASSERT(current_block()->HasPredecessor()); |
10275 EqualityKind kind = | 10360 EqualityKind kind = |
10276 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; | 10361 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; |
10277 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil); | 10362 HIfContinuation continuation; |
10278 instr->set_position(expr->position()); | 10363 TypeFeedbackId id = expr->CompareOperationFeedbackId(); |
10279 return ast_context()->ReturnControl(instr, expr->id()); | 10364 CompareNilICStub::Types types; |
| 10365 if (kind == kStrictEquality) { |
| 10366 if (nil == kNullValue) { |
| 10367 types = CompareNilICStub::kCompareAgainstNull; |
| 10368 } else { |
| 10369 types = CompareNilICStub::kCompareAgainstUndefined; |
| 10370 } |
| 10371 } else { |
| 10372 types = static_cast<CompareNilICStub::Types>( |
| 10373 oracle()->CompareNilTypes(id)); |
| 10374 if (types == 0) types = CompareNilICStub::kFullCompare; |
| 10375 } |
| 10376 Handle<Map> map_handle(oracle()->CompareNilMonomorphicReceiverType(id)); |
| 10377 BuildCompareNil(value, kind, types, map_handle, |
| 10378 expr->position(), &continuation); |
| 10379 return ast_context()->ReturnContinuation(&continuation, expr->id()); |
10280 } | 10380 } |
10281 | 10381 |
10282 | 10382 |
10283 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { | 10383 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { |
10284 // If we share optimized code between different closures, the | 10384 // If we share optimized code between different closures, the |
10285 // this-function is not a constant, except inside an inlined body. | 10385 // this-function is not a constant, except inside an inlined body. |
10286 if (function_state()->outer() != NULL) { | 10386 if (function_state()->outer() != NULL) { |
10287 return new(zone()) HConstant( | 10387 return new(zone()) HConstant( |
10288 function_state()->compilation_info()->closure(), | 10388 function_state()->compilation_info()->closure(), |
10289 Representation::Tagged()); | 10389 Representation::Tagged()); |
(...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11872 } | 11972 } |
11873 } | 11973 } |
11874 | 11974 |
11875 #ifdef DEBUG | 11975 #ifdef DEBUG |
11876 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11976 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11877 if (allocator_ != NULL) allocator_->Verify(); | 11977 if (allocator_ != NULL) allocator_->Verify(); |
11878 #endif | 11978 #endif |
11879 } | 11979 } |
11880 | 11980 |
11881 } } // namespace v8::internal | 11981 } } // namespace v8::internal |
OLD | NEW |