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 23 matching lines...) Expand all Loading... | |
869 HBasicBlock* block = builder_->current_block(); | 895 HBasicBlock* block = builder_->current_block(); |
870 block->FinishExitWithDeoptimization(HDeoptimize::kUseAll); | 896 block->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
871 if (did_else_) { | 897 if (did_else_) { |
872 first_false_block_ = NULL; | 898 first_false_block_ = NULL; |
873 } else { | 899 } else { |
874 first_true_block_ = NULL; | 900 first_true_block_ = NULL; |
875 } | 901 } |
876 } | 902 } |
877 | 903 |
878 | 904 |
905 void HGraphBuilder::IfBuilder::Return(HValue* value) { | |
906 ASSERT(!(did_then_ ^ did_else_)); | |
mvstanton
2013/04/23 09:27:30
I'd probably comment this in english: "Make sure w
danno
2013/04/23 16:14:47
Done.
| |
907 HBasicBlock* block = builder_->current_block(); | |
908 block->Finish(new(zone()) HReturn(value, | |
909 builder_->environment()->LookupContext(), | |
910 builder_->graph()->GetConstantMinus1())); | |
911 if (did_else_) { | |
912 first_false_block_ = NULL; | |
913 } else { | |
914 first_true_block_ = NULL; | |
915 } | |
916 } | |
917 | |
918 | |
879 void HGraphBuilder::IfBuilder::End() { | 919 void HGraphBuilder::IfBuilder::End() { |
880 if (!captured_) { | 920 if (!captured_) { |
881 ASSERT(did_then_); | 921 ASSERT(did_then_); |
882 if (!did_else_) { | 922 if (!did_else_) { |
883 last_true_block_ = builder_->current_block(); | 923 last_true_block_ = builder_->current_block(); |
884 } | 924 } |
885 if (first_true_block_ == NULL) { | 925 if (first_true_block_ == NULL) { |
886 // Deopt on true. Nothing to do, just continue the false block. | 926 // Deopt on true. Nothing to do, just continue the false block. |
887 } else if (first_false_block_ == NULL) { | 927 } else if (first_false_block_ == NULL) { |
888 // Deopt on false. Nothing to do except switching to the true block. | 928 // 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, | 1765 key_constant, |
1726 value, | 1766 value, |
1727 kind)); | 1767 kind)); |
1728 } | 1768 } |
1729 } | 1769 } |
1730 | 1770 |
1731 return object; | 1771 return object; |
1732 } | 1772 } |
1733 | 1773 |
1734 | 1774 |
1775 void HGraphBuilder::BuildCompareNil( | |
1776 HValue* value, | |
1777 EqualityKind kind, | |
1778 CompareNilICStub::Types types, | |
1779 Handle<Map> map, | |
1780 int position, | |
1781 HIfContinuation* continuation) { | |
1782 IfBuilder if_nil(this, position); | |
1783 bool needs_or = false; | |
1784 if ((types & CompareNilICStub::kCompareAgainstNull) != 0) { | |
1785 if (needs_or) if_nil.Or(); | |
1786 if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull()); | |
1787 needs_or = true; | |
1788 } | |
1789 if ((types & CompareNilICStub::kCompareAgainstUndefined) != 0) { | |
1790 if (needs_or) if_nil.Or(); | |
1791 if_nil.If<HCompareObjectEqAndBranch>(value, | |
1792 graph()->GetConstantUndefined()); | |
1793 needs_or = true; | |
1794 } | |
1795 // Handle either undetectable or monomorphic, not both. | |
1796 ASSERT(((types & CompareNilICStub::kCompareAgainstUndetectable) == 0) || | |
1797 ((types & CompareNilICStub::kCompareAgainstMonomorphicMap) == 0)); | |
1798 if ((types & CompareNilICStub::kCompareAgainstUndetectable) != 0) { | |
1799 if (needs_or) if_nil.Or(); | |
1800 if_nil.If<HIsUndetectableAndBranch>(value); | |
1801 } else { | |
1802 if_nil.Then(); | |
1803 if_nil.Else(); | |
1804 if ((types & CompareNilICStub::kCompareAgainstMonomorphicMap) != 0) { | |
1805 BuildCheckNonSmi(value); | |
1806 BuildCheckMap(value, map); | |
mvstanton
2013/04/23 09:27:30
As I understand it, this BuildCheckMap is importan
danno
2013/04/23 16:14:47
Done.
| |
1807 } else { | |
1808 if (kind == kNonStrictEquality) { | |
1809 if_nil.Deopt(); | |
1810 } | |
1811 } | |
1812 } | |
1813 | |
1814 if_nil.CaptureContinuation(continuation); | |
1815 } | |
1816 | |
1817 | |
1735 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1818 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
1736 TypeFeedbackOracle* oracle) | 1819 TypeFeedbackOracle* oracle) |
1737 : HGraphBuilder(info), | 1820 : HGraphBuilder(info), |
1738 function_state_(NULL), | 1821 function_state_(NULL), |
1739 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1822 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
1740 ast_context_(NULL), | 1823 ast_context_(NULL), |
1741 break_scope_(NULL), | 1824 break_scope_(NULL), |
1742 inlined_count_(0), | 1825 inlined_count_(0), |
1743 globals_(10, info->zone()), | 1826 globals_(10, info->zone()), |
1744 inline_bailout_(false) { | 1827 inline_bailout_(false) { |
(...skipping 8522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10267 | 10350 |
10268 | 10351 |
10269 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 10352 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
10270 HValue* value, | 10353 HValue* value, |
10271 NilValue nil) { | 10354 NilValue nil) { |
10272 ASSERT(!HasStackOverflow()); | 10355 ASSERT(!HasStackOverflow()); |
10273 ASSERT(current_block() != NULL); | 10356 ASSERT(current_block() != NULL); |
10274 ASSERT(current_block()->HasPredecessor()); | 10357 ASSERT(current_block()->HasPredecessor()); |
10275 EqualityKind kind = | 10358 EqualityKind kind = |
10276 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; | 10359 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; |
10277 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil); | 10360 HIfContinuation continuation; |
10278 instr->set_position(expr->position()); | 10361 TypeFeedbackId id = expr->CompareOperationFeedbackId(); |
10279 return ast_context()->ReturnControl(instr, expr->id()); | 10362 CompareNilICStub::Types types; |
10363 if (kind == kStrictEquality) { | |
10364 if (nil == kNullValue) { | |
10365 types = CompareNilICStub::kCompareAgainstNull; | |
10366 } else { | |
10367 types = CompareNilICStub::kCompareAgainstUndefined; | |
10368 } | |
10369 } else { | |
10370 types = static_cast<CompareNilICStub::Types>( | |
10371 oracle()->CompareNilTypes(id)); | |
10372 if (types == 0) types = CompareNilICStub::kFullCompare; | |
10373 } | |
10374 Handle<Map> map_handle(oracle()->CompareNilMonomorphicReceiverType(id)); | |
10375 BuildCompareNil(value, kind, types, map_handle, | |
10376 expr->position(), &continuation); | |
10377 return ast_context()->ReturnContinuation(&continuation, expr->id()); | |
10280 } | 10378 } |
10281 | 10379 |
10282 | 10380 |
10283 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { | 10381 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { |
10284 // If we share optimized code between different closures, the | 10382 // If we share optimized code between different closures, the |
10285 // this-function is not a constant, except inside an inlined body. | 10383 // this-function is not a constant, except inside an inlined body. |
10286 if (function_state()->outer() != NULL) { | 10384 if (function_state()->outer() != NULL) { |
10287 return new(zone()) HConstant( | 10385 return new(zone()) HConstant( |
10288 function_state()->compilation_info()->closure(), | 10386 function_state()->compilation_info()->closure(), |
10289 Representation::Tagged()); | 10387 Representation::Tagged()); |
(...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11872 } | 11970 } |
11873 } | 11971 } |
11874 | 11972 |
11875 #ifdef DEBUG | 11973 #ifdef DEBUG |
11876 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11974 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11877 if (allocator_ != NULL) allocator_->Verify(); | 11975 if (allocator_ != NULL) allocator_->Verify(); |
11878 #endif | 11976 #endif |
11879 } | 11977 } |
11880 | 11978 |
11881 } } // namespace v8::internal | 11979 } } // namespace v8::internal |
OLD | NEW |