Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(328)

Side by Side Diff: src/hydrogen.cc

Issue 14367018: Add monomorphic CompareNilICs and Crankshaft support (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698