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

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: Fix crash 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
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 23 matching lines...) Expand all
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698