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

Side by Side Diff: src/hydrogen.cc

Issue 13728002: Add an IC for CompareNil operations (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix SunSpider regression 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 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 key_constant, 1751 key_constant,
1727 value, 1752 value,
1728 kind)); 1753 kind));
1729 } 1754 }
1730 } 1755 }
1731 1756
1732 return object; 1757 return object;
1733 } 1758 }
1734 1759
1735 1760
1761 void HGraphBuilder::BuildCompareNil(
1762 HValue* value,
1763 EqualityKind kind,
1764 CompareNilICStub::Types types,
1765 Handle<Map> map,
1766 int position,
1767 HIfContinuation* continuation) {
1768 IfBuilder if_nil(this, position);
1769 bool needs_or = false;
1770 if ((types & CompareNilICStub::kCompareAgainstNull) != 0) {
1771 if (needs_or) if_nil.Or();
1772 if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull());
1773 needs_or = true;
1774 }
1775 if ((types & CompareNilICStub::kCompareAgainstUndefined) != 0) {
1776 if (needs_or) if_nil.Or();
1777 if_nil.If<HCompareObjectEqAndBranch>(value,
1778 graph()->GetConstantUndefined());
1779 needs_or = true;
1780 }
1781 // Handle either undetectable or monomorphic, not both.
1782 ASSERT(((types & CompareNilICStub::kCompareAgainstUndetectable) == 0) ||
1783 ((types & CompareNilICStub::kCompareAgainstMonomorphicMap) == 0));
1784 if ((types & CompareNilICStub::kCompareAgainstUndetectable) != 0) {
1785 if (needs_or) if_nil.Or();
1786 if_nil.If<HIsUndetectableAndBranch>(value);
1787 } else {
1788 if_nil.Then();
1789 if_nil.Else();
1790 if ((types & CompareNilICStub::kCompareAgainstMonomorphicMap) != 0) {
1791 BuildCheckNonSmi(value);
1792 BuildCheckMap(value, map);
1793 } else {
1794 if (kind == kNonStrictEquality) {
1795 if_nil.Deopt();
1796 }
1797 }
1798 }
1799
1800 if_nil.CaptureContinuation(continuation);
1801 }
1802
1803
1736 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, 1804 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
1737 TypeFeedbackOracle* oracle) 1805 TypeFeedbackOracle* oracle)
1738 : HGraphBuilder(info), 1806 : HGraphBuilder(info),
1739 function_state_(NULL), 1807 function_state_(NULL),
1740 initial_function_state_(this, info, oracle, NORMAL_RETURN), 1808 initial_function_state_(this, info, oracle, NORMAL_RETURN),
1741 ast_context_(NULL), 1809 ast_context_(NULL),
1742 break_scope_(NULL), 1810 break_scope_(NULL),
1743 inlined_count_(0), 1811 inlined_count_(0),
1744 globals_(10, info->zone()), 1812 globals_(10, info->zone()),
1745 inline_bailout_(false) { 1813 inline_bailout_(false) {
(...skipping 8301 matching lines...) Expand 10 before | Expand all | Expand 10 after
10047 HTypeof* typeof_expr, 10115 HTypeof* typeof_expr,
10048 Handle<String> check) { 10116 Handle<String> check) {
10049 // Note: The HTypeof itself is removed during canonicalization, if possible. 10117 // Note: The HTypeof itself is removed during canonicalization, if possible.
10050 HValue* value = typeof_expr->value(); 10118 HValue* value = typeof_expr->value();
10051 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); 10119 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check);
10052 instr->set_position(expr->position()); 10120 instr->set_position(expr->position());
10053 return ast_context()->ReturnControl(instr, expr->id()); 10121 return ast_context()->ReturnControl(instr, expr->id());
10054 } 10122 }
10055 10123
10056 10124
10057 static bool MatchLiteralCompareNil(HValue* left,
10058 Token::Value op,
10059 HValue* right,
10060 Handle<Object> nil,
10061 HValue** expr) {
10062 if (left->IsConstant() &&
10063 HConstant::cast(left)->handle().is_identical_to(nil) &&
10064 Token::IsEqualityOp(op)) {
10065 *expr = right;
10066 return true;
10067 }
10068 return false;
10069 }
10070
10071
10072 static bool MatchLiteralCompareTypeof(HValue* left, 10125 static bool MatchLiteralCompareTypeof(HValue* left,
10073 Token::Value op, 10126 Token::Value op,
10074 HValue* right, 10127 HValue* right,
10075 HTypeof** typeof_expr, 10128 HTypeof** typeof_expr,
10076 Handle<String>* check) { 10129 Handle<String>* check) {
10077 if (left->IsTypeof() && 10130 if (left->IsTypeof() &&
10078 Token::IsEqualityOp(op) && 10131 Token::IsEqualityOp(op) &&
10079 right->IsConstant() && 10132 right->IsConstant() &&
10080 HConstant::cast(right)->handle()->IsString()) { 10133 HConstant::cast(right)->handle()->IsString()) {
10081 *typeof_expr = HTypeof::cast(left); 10134 *typeof_expr = HTypeof::cast(left);
10082 *check = Handle<String>::cast(HConstant::cast(right)->handle()); 10135 *check = Handle<String>::cast(HConstant::cast(right)->handle());
10083 return true; 10136 return true;
10084 } 10137 }
10085 return false; 10138 return false;
10086 } 10139 }
10087 10140
10088 10141
10089 static bool IsLiteralCompareTypeof(HValue* left, 10142 static bool IsLiteralCompareTypeof(HValue* left,
10090 Token::Value op, 10143 Token::Value op,
10091 HValue* right, 10144 HValue* right,
10092 HTypeof** typeof_expr, 10145 HTypeof** typeof_expr,
10093 Handle<String>* check) { 10146 Handle<String>* check) {
10094 return MatchLiteralCompareTypeof(left, op, right, typeof_expr, check) || 10147 return MatchLiteralCompareTypeof(left, op, right, typeof_expr, check) ||
10095 MatchLiteralCompareTypeof(right, op, left, typeof_expr, check); 10148 MatchLiteralCompareTypeof(right, op, left, typeof_expr, check);
10096 } 10149 }
10097 10150
10098 10151
10099 static bool IsLiteralCompareNil(HValue* left,
10100 Token::Value op,
10101 HValue* right,
10102 Handle<Object> nil,
10103 HValue** expr) {
10104 return MatchLiteralCompareNil(left, op, right, nil, expr) ||
10105 MatchLiteralCompareNil(right, op, left, nil, expr);
10106 }
10107
10108
10109 static bool IsLiteralCompareBool(HValue* left, 10152 static bool IsLiteralCompareBool(HValue* left,
10110 Token::Value op, 10153 Token::Value op,
10111 HValue* right) { 10154 HValue* right) {
10112 return op == Token::EQ_STRICT && 10155 return op == Token::EQ_STRICT &&
10113 ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) || 10156 ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) ||
10114 (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean())); 10157 (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean()));
10115 } 10158 }
10116 10159
10117 10160
10118 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 10161 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
10150 HValue* context = environment()->LookupContext(); 10193 HValue* context = environment()->LookupContext();
10151 HValue* right = Pop(); 10194 HValue* right = Pop();
10152 HValue* left = Pop(); 10195 HValue* left = Pop();
10153 Token::Value op = expr->op(); 10196 Token::Value op = expr->op();
10154 10197
10155 HTypeof* typeof_expr = NULL; 10198 HTypeof* typeof_expr = NULL;
10156 Handle<String> check; 10199 Handle<String> check;
10157 if (IsLiteralCompareTypeof(left, op, right, &typeof_expr, &check)) { 10200 if (IsLiteralCompareTypeof(left, op, right, &typeof_expr, &check)) {
10158 return HandleLiteralCompareTypeof(expr, typeof_expr, check); 10201 return HandleLiteralCompareTypeof(expr, typeof_expr, check);
10159 } 10202 }
10160 HValue* sub_expr = NULL; 10203
10161 Factory* f = isolate()->factory(); 10204 Expression* sub_expr = NULL;
10162 if (IsLiteralCompareNil(left, op, right, f->undefined_value(), &sub_expr)) { 10205 if (expr->IsLiteralCompareNull(&sub_expr)) {
10163 return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); 10206 HValue* sub_expr_value = sub_expr == expr->left() ? left : right;
10207 return HandleLiteralCompareNil(expr, sub_expr_value, kNullValue);
10164 } 10208 }
10165 if (IsLiteralCompareNil(left, op, right, f->null_value(), &sub_expr)) { 10209 if (expr->IsLiteralCompareUndefined(&sub_expr)) {
10166 return HandleLiteralCompareNil(expr, sub_expr, kNullValue); 10210 HValue* sub_expr_value = sub_expr == expr->left() ? left : right;
10211 return HandleLiteralCompareNil(expr, sub_expr_value, kUndefinedValue);
10167 } 10212 }
10168 if (IsLiteralCompareBool(left, op, right)) { 10213 if (IsLiteralCompareBool(left, op, right)) {
10169 HCompareObjectEqAndBranch* result = 10214 HCompareObjectEqAndBranch* result =
10170 new(zone()) HCompareObjectEqAndBranch(left, right); 10215 new(zone()) HCompareObjectEqAndBranch(left, right);
10171 result->set_position(expr->position()); 10216 result->set_position(expr->position());
10172 return ast_context()->ReturnControl(result, expr->id()); 10217 return ast_context()->ReturnControl(result, expr->id());
10173 } 10218 }
10174 10219
10175 if (op == Token::INSTANCEOF) { 10220 if (op == Token::INSTANCEOF) {
10176 // Check to see if the rhs of the instanceof is a global function not 10221 // Check to see if the rhs of the instanceof is a global function not
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
10269 10314
10270 10315
10271 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 10316 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
10272 HValue* value, 10317 HValue* value,
10273 NilValue nil) { 10318 NilValue nil) {
10274 ASSERT(!HasStackOverflow()); 10319 ASSERT(!HasStackOverflow());
10275 ASSERT(current_block() != NULL); 10320 ASSERT(current_block() != NULL);
10276 ASSERT(current_block()->HasPredecessor()); 10321 ASSERT(current_block()->HasPredecessor());
10277 EqualityKind kind = 10322 EqualityKind kind =
10278 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; 10323 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality;
10279 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil); 10324 HIfContinuation continuation;
10280 instr->set_position(expr->position()); 10325 TypeFeedbackId id = expr->CompareOperationFeedbackId();
10281 return ast_context()->ReturnControl(instr, expr->id()); 10326 CompareNilICStub::Types types;
10327 if (kind == kStrictEquality) {
10328 if (nil == kNullValue) {
10329 types = CompareNilICStub::kCompareAgainstNull;
10330 } else {
10331 types = CompareNilICStub::kCompareAgainstUndefined;
10332 }
10333 } else {
10334 types = static_cast<CompareNilICStub::Types>(
10335 oracle()->CompareNilTypes(id));
10336 if (types == 0) types = CompareNilICStub::kFullCompare;
10337 }
10338 Handle<Map> map_handle(oracle()->CompareNilMonomorphicReceiverType(id));
10339 BuildCompareNil(value, kind, types, map_handle,
10340 expr->position(), &continuation);
10341 return ast_context()->ReturnContinuation(&continuation, expr->id());
10282 } 10342 }
10283 10343
10284 10344
10285 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 10345 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
10286 // If we share optimized code between different closures, the 10346 // If we share optimized code between different closures, the
10287 // this-function is not a constant, except inside an inlined body. 10347 // this-function is not a constant, except inside an inlined body.
10288 if (function_state()->outer() != NULL) { 10348 if (function_state()->outer() != NULL) {
10289 return new(zone()) HConstant( 10349 return new(zone()) HConstant(
10290 function_state()->compilation_info()->closure(), 10350 function_state()->compilation_info()->closure(),
10291 Representation::Tagged()); 10351 Representation::Tagged());
(...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after
11874 } 11934 }
11875 } 11935 }
11876 11936
11877 #ifdef DEBUG 11937 #ifdef DEBUG
11878 if (graph_ != NULL) graph_->Verify(false); // No full verify. 11938 if (graph_ != NULL) graph_->Verify(false); // No full verify.
11879 if (allocator_ != NULL) allocator_->Verify(); 11939 if (allocator_ != NULL) allocator_->Verify();
11880 #endif 11940 #endif
11881 } 11941 }
11882 11942
11883 } } // namespace v8::internal 11943 } } // 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