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

Side by Side Diff: src/hydrogen.cc

Issue 8242002: Recognize special comparisons via pattern matching on the hydrogen graph. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 2 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 5772 matching lines...) Expand 10 before | Expand all | Expand 10 after
5783 5783
5784 Representation HGraphBuilder::ToRepresentation(TypeInfo info) { 5784 Representation HGraphBuilder::ToRepresentation(TypeInfo info) {
5785 if (info.IsSmi()) return Representation::Integer32(); 5785 if (info.IsSmi()) return Representation::Integer32();
5786 if (info.IsInteger32()) return Representation::Integer32(); 5786 if (info.IsInteger32()) return Representation::Integer32();
5787 if (info.IsDouble()) return Representation::Double(); 5787 if (info.IsDouble()) return Representation::Double();
5788 if (info.IsNumber()) return Representation::Double(); 5788 if (info.IsNumber()) return Representation::Double();
5789 return Representation::Tagged(); 5789 return Representation::Tagged();
5790 } 5790 }
5791 5791
5792 5792
5793 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 5793 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
Kevin Millikin (Chromium) 2011/10/13 13:11:59 I'd prefer to use more specific types here. The c
Sven Panne 2011/10/13 14:21:38 Done.
5794 Expression* sub_expr, 5794 HValue* typeof_expr,
5795 Handle<String> check) { 5795 HValue* check) {
5796 CHECK_ALIVE(VisitForTypeOf(sub_expr)); 5796 HValue* value = HTypeof::cast(typeof_expr)->value();
5797 HValue* value = Pop(); 5797 Handle<String> blah = Handle<String>::cast(HConstant::cast(check)->handle());
Kevin Millikin (Chromium) 2011/10/13 13:11:59 There must be a better name.
Sven Panne 2011/10/13 14:21:38 hurz? (http://www.youtube.com/watch?v=RAx0P-8n5K4)
5798 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); 5798 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, blah);
5799 instr->set_position(expr->position()); 5799 instr->set_position(expr->position());
5800 return ast_context()->ReturnControl(instr, expr->id()); 5800 ast_context()->ReturnControl(instr, expr->id());
5801 typeof_expr->DeleteAndReplaceWith(instr);
Kevin Millikin (Chromium) 2011/10/13 13:11:59 I don't think this is right. instr is a control i
Sven Panne 2011/10/13 14:21:38 I'd like to go for the first alternative (replacin
5801 } 5802 }
5802 5803
5803 5804
5804 bool HGraphBuilder::TryLiteralCompare(CompareOperation* expr) { 5805 static bool MatchLiteralCompareNil(HValue* left,
5805 Expression *sub_expr; 5806 Token::Value op,
5806 Handle<String> check; 5807 HValue* right,
5807 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 5808 Handle<Object> nil,
5808 HandleLiteralCompareTypeof(expr, sub_expr, check); 5809 HValue** expr) {
5810 if (left->IsConstant() &&
5811 HConstant::cast(left)->handle().is_identical_to(nil) &&
5812 Token::IsEqualityOp(op)) {
5813 *expr = right;
5809 return true; 5814 return true;
5810 } 5815 }
5816 return false;
5817 }
5811 5818
5812 if (expr->IsLiteralCompareUndefined(&sub_expr)) { 5819
5813 HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); 5820 static bool MatchLiteralCompareTypeof(HValue* left,
5821 Token::Value op,
5822 HValue* right,
5823 HValue** typeof_expr,
5824 HValue** check) {
5825 if (left->IsTypeof() &&
5826 Token::IsEqualityOp(op) &&
5827 right->IsConstant() &&
5828 HConstant::cast(right)->HasStringValue()) {
5829 *typeof_expr = left;
Kevin Millikin (Chromium) 2011/10/13 13:11:59 If you take my suggestion above, this is where you
Sven Panne 2011/10/13 14:21:38 Done.
5830 *check = right;
5814 return true; 5831 return true;
5815 } 5832 }
5833 return false;
5834 }
5816 5835
5817 if (expr->IsLiteralCompareNull(&sub_expr)) {
5818 HandleLiteralCompareNil(expr, sub_expr, kNullValue);
5819 return true;
5820 }
5821 5836
5822 return false; 5837 static bool IsLiteralCompareTypeof(HValue* left,
5838 Token::Value op,
5839 HValue* right,
5840 HValue** typeof_expr,
5841 HValue** check) {
5842 return MatchLiteralCompareTypeof(left, op, right, typeof_expr, check) ||
5843 MatchLiteralCompareTypeof(right, op, left, typeof_expr, check);
5844 }
5845
5846
5847 static bool IsLiteralCompareNil(HValue* left,
5848 Token::Value op,
5849 HValue* right,
5850 Handle<Object> nil,
5851 HValue** expr) {
5852 return MatchLiteralCompareNil(left, op, right, nil, expr) ||
5853 MatchLiteralCompareNil(right, op, left, nil, expr);
5823 } 5854 }
5824 5855
5825 5856
5826 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 5857 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
5827 ASSERT(!HasStackOverflow()); 5858 ASSERT(!HasStackOverflow());
5828 ASSERT(current_block() != NULL); 5859 ASSERT(current_block() != NULL);
5829 ASSERT(current_block()->HasPredecessor()); 5860 ASSERT(current_block()->HasPredecessor());
5830 if (IsClassOfTest(expr)) { 5861 if (IsClassOfTest(expr)) {
5831 CallRuntime* call = expr->left()->AsCallRuntime(); 5862 CallRuntime* call = expr->left()->AsCallRuntime();
5832 ASSERT(call->arguments()->length() == 1); 5863 ASSERT(call->arguments()->length() == 1);
5833 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5864 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5834 HValue* value = Pop(); 5865 HValue* value = Pop();
5835 Literal* literal = expr->right()->AsLiteral(); 5866 Literal* literal = expr->right()->AsLiteral();
5836 Handle<String> rhs = Handle<String>::cast(literal->handle()); 5867 Handle<String> rhs = Handle<String>::cast(literal->handle());
5837 HClassOfTestAndBranch* instr = 5868 HClassOfTestAndBranch* instr =
5838 new(zone()) HClassOfTestAndBranch(value, rhs); 5869 new(zone()) HClassOfTestAndBranch(value, rhs);
5839 instr->set_position(expr->position()); 5870 instr->set_position(expr->position());
5840 return ast_context()->ReturnControl(instr, expr->id()); 5871 return ast_context()->ReturnControl(instr, expr->id());
5841 } 5872 }
5842 5873
5843 // Check for special cases that compare against literals.
5844 if (TryLiteralCompare(expr)) return;
5845
5846 TypeInfo type_info = oracle()->CompareType(expr); 5874 TypeInfo type_info = oracle()->CompareType(expr);
5847 // Check if this expression was ever executed according to type feedback. 5875 // Check if this expression was ever executed according to type feedback.
5876 // Note that for the special typeof/null/undefined cases we get unknown here.
5848 if (type_info.IsUninitialized()) { 5877 if (type_info.IsUninitialized()) {
5849 AddInstruction(new(zone()) HSoftDeoptimize); 5878 AddInstruction(new(zone()) HSoftDeoptimize);
5850 current_block()->MarkAsDeoptimizing(); 5879 current_block()->MarkAsDeoptimizing();
5851 type_info = TypeInfo::Unknown(); 5880 type_info = TypeInfo::Unknown();
5852 } 5881 }
5853 5882
5854 CHECK_ALIVE(VisitForValue(expr->left())); 5883 CHECK_ALIVE(VisitForValue(expr->left()));
5855 CHECK_ALIVE(VisitForValue(expr->right())); 5884 CHECK_ALIVE(VisitForValue(expr->right()));
5856 5885
5857 HValue* context = environment()->LookupContext(); 5886 HValue* context = environment()->LookupContext();
5858 HValue* right = Pop(); 5887 HValue* right = Pop();
5859 HValue* left = Pop(); 5888 HValue* left = Pop();
5860 Token::Value op = expr->op(); 5889 Token::Value op = expr->op();
5861 5890
5891 HValue* typeof_expr = NULL;
Kevin Millikin (Chromium) 2011/10/13 13:11:59 And HTypeof* typeof_expr = NULL; Handle<String> c
Sven Panne 2011/10/13 14:21:38 Done.
5892 HValue* check = NULL;
5893 if (IsLiteralCompareTypeof(left, op, right, &typeof_expr, &check)) {
5894 return HandleLiteralCompareTypeof(expr, typeof_expr, check);
5895 }
5896 HValue* sub_expr = NULL;
5897 Factory* f = graph()->isolate()->factory();
5898 if (IsLiteralCompareNil(left, op, right, f->undefined_value(), &sub_expr)) {
5899 return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
5900 }
5901 if (IsLiteralCompareNil(left, op, right, f->null_value(), &sub_expr)) {
5902 return HandleLiteralCompareNil(expr, sub_expr, kNullValue);
5903 }
5904
5862 if (op == Token::INSTANCEOF) { 5905 if (op == Token::INSTANCEOF) {
5863 // Check to see if the rhs of the instanceof is a global function not 5906 // Check to see if the rhs of the instanceof is a global function not
5864 // residing in new space. If it is we assume that the function will stay the 5907 // residing in new space. If it is we assume that the function will stay the
5865 // same. 5908 // same.
5866 Handle<JSFunction> target = Handle<JSFunction>::null(); 5909 Handle<JSFunction> target = Handle<JSFunction>::null();
5867 VariableProxy* proxy = expr->right()->AsVariableProxy(); 5910 VariableProxy* proxy = expr->right()->AsVariableProxy();
5868 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); 5911 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated();
5869 if (global_function && 5912 if (global_function &&
5870 info()->has_global_object() && 5913 info()->has_global_object() &&
5871 !info()->global_object()->IsAccessCheckNeeded()) { 5914 !info()->global_object()->IsAccessCheckNeeded()) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
5940 new(zone()) HCompareIDAndBranch(left, right, op); 5983 new(zone()) HCompareIDAndBranch(left, right, op);
5941 result->set_position(expr->position()); 5984 result->set_position(expr->position());
5942 result->SetInputRepresentation(r); 5985 result->SetInputRepresentation(r);
5943 return ast_context()->ReturnControl(result, expr->id()); 5986 return ast_context()->ReturnControl(result, expr->id());
5944 } 5987 }
5945 } 5988 }
5946 } 5989 }
5947 5990
5948 5991
5949 void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 5992 void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
5950 Expression* sub_expr, 5993 HValue* value,
5951 NilValue nil) { 5994 NilValue nil) {
5952 ASSERT(!HasStackOverflow()); 5995 ASSERT(!HasStackOverflow());
5953 ASSERT(current_block() != NULL); 5996 ASSERT(current_block() != NULL);
5954 ASSERT(current_block()->HasPredecessor()); 5997 ASSERT(current_block()->HasPredecessor());
5955 CHECK_ALIVE(VisitForValue(sub_expr));
5956 HValue* value = Pop();
5957 EqualityKind kind = 5998 EqualityKind kind =
5958 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; 5999 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality;
5959 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil); 6000 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil);
5960 instr->set_position(expr->position()); 6001 instr->set_position(expr->position());
5961 return ast_context()->ReturnControl(instr, expr->id()); 6002 return ast_context()->ReturnControl(instr, expr->id());
5962 } 6003 }
5963 6004
5964 6005
5965 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { 6006 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
5966 ASSERT(!HasStackOverflow()); 6007 ASSERT(!HasStackOverflow());
(...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after
6939 } 6980 }
6940 } 6981 }
6941 6982
6942 #ifdef DEBUG 6983 #ifdef DEBUG
6943 if (graph_ != NULL) graph_->Verify(false); // No full verify. 6984 if (graph_ != NULL) graph_->Verify(false); // No full verify.
6944 if (allocator_ != NULL) allocator_->Verify(); 6985 if (allocator_ != NULL) allocator_->Verify();
6945 #endif 6986 #endif
6946 } 6987 }
6947 6988
6948 } } // namespace v8::internal 6989 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698