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

Side by Side Diff: src/hydrogen.cc

Issue 8334021: Recognize special comparisons via pattern matching on the hydrogen graph, 2nd attempt. (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
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 5771 matching lines...) Expand 10 before | Expand all | Expand 10 after
5782 Representation HGraphBuilder::ToRepresentation(TypeInfo info) { 5782 Representation HGraphBuilder::ToRepresentation(TypeInfo info) {
5783 if (info.IsSmi()) return Representation::Integer32(); 5783 if (info.IsSmi()) return Representation::Integer32();
5784 if (info.IsInteger32()) return Representation::Integer32(); 5784 if (info.IsInteger32()) return Representation::Integer32();
5785 if (info.IsDouble()) return Representation::Double(); 5785 if (info.IsDouble()) return Representation::Double();
5786 if (info.IsNumber()) return Representation::Double(); 5786 if (info.IsNumber()) return Representation::Double();
5787 return Representation::Tagged(); 5787 return Representation::Tagged();
5788 } 5788 }
5789 5789
5790 5790
5791 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 5791 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
5792 Expression* sub_expr, 5792 HTypeof* typeof_expr,
5793 Handle<String> check) { 5793 Handle<String> check) {
5794 CHECK_ALIVE(VisitForTypeOf(sub_expr)); 5794 // Note: The HTypeof itself is removed during canonicalization, if possible.
5795 HValue* value = Pop(); 5795 HValue* value = typeof_expr->value();
5796 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); 5796 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check);
5797 instr->set_position(expr->position()); 5797 instr->set_position(expr->position());
5798 return ast_context()->ReturnControl(instr, expr->id()); 5798 ast_context()->ReturnControl(instr, expr->id());
Kevin Millikin (Chromium) 2011/10/19 07:24:41 I like the "return". This function is (sort of) a
Sven Panne 2011/10/19 07:33:32 Done. Personally I like returning void, too, it is
5799 } 5799 }
5800 5800
5801 5801
5802 bool HGraphBuilder::TryLiteralCompare(CompareOperation* expr) { 5802 static bool MatchLiteralCompareNil(HValue* left,
5803 Expression *sub_expr; 5803 Token::Value op,
5804 Handle<String> check; 5804 HValue* right,
5805 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 5805 Handle<Object> nil,
5806 HandleLiteralCompareTypeof(expr, sub_expr, check); 5806 HValue** expr) {
5807 if (left->IsConstant() &&
5808 HConstant::cast(left)->handle().is_identical_to(nil) &&
5809 Token::IsEqualityOp(op)) {
5810 *expr = right;
5807 return true; 5811 return true;
5808 } 5812 }
5813 return false;
5814 }
5809 5815
5810 if (expr->IsLiteralCompareUndefined(&sub_expr)) { 5816
5811 HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); 5817 static bool MatchLiteralCompareTypeof(HValue* left,
5818 Token::Value op,
5819 HValue* right,
5820 HTypeof** typeof_expr,
5821 Handle<String>* check) {
5822 if (left->IsTypeof() &&
5823 Token::IsEqualityOp(op) &&
5824 right->IsConstant() &&
5825 HConstant::cast(right)->HasStringValue()) {
5826 *typeof_expr = HTypeof::cast(left);
5827 *check = Handle<String>::cast(HConstant::cast(right)->handle());
5812 return true; 5828 return true;
5813 } 5829 }
5830 return false;
5831 }
5814 5832
5815 if (expr->IsLiteralCompareNull(&sub_expr)) {
5816 HandleLiteralCompareNil(expr, sub_expr, kNullValue);
5817 return true;
5818 }
5819 5833
5820 return false; 5834 static bool IsLiteralCompareTypeof(HValue* left,
5835 Token::Value op,
5836 HValue* right,
5837 HTypeof** typeof_expr,
5838 Handle<String>* check) {
5839 return MatchLiteralCompareTypeof(left, op, right, typeof_expr, check) ||
5840 MatchLiteralCompareTypeof(right, op, left, typeof_expr, check);
5841 }
5842
5843
5844 static bool IsLiteralCompareNil(HValue* left,
5845 Token::Value op,
5846 HValue* right,
5847 Handle<Object> nil,
5848 HValue** expr) {
5849 return MatchLiteralCompareNil(left, op, right, nil, expr) ||
5850 MatchLiteralCompareNil(right, op, left, nil, expr);
5821 } 5851 }
5822 5852
5823 5853
5824 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 5854 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
5825 ASSERT(!HasStackOverflow()); 5855 ASSERT(!HasStackOverflow());
5826 ASSERT(current_block() != NULL); 5856 ASSERT(current_block() != NULL);
5827 ASSERT(current_block()->HasPredecessor()); 5857 ASSERT(current_block()->HasPredecessor());
5828 if (IsClassOfTest(expr)) { 5858 if (IsClassOfTest(expr)) {
5829 CallRuntime* call = expr->left()->AsCallRuntime(); 5859 CallRuntime* call = expr->left()->AsCallRuntime();
5830 ASSERT(call->arguments()->length() == 1); 5860 ASSERT(call->arguments()->length() == 1);
5831 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5861 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5832 HValue* value = Pop(); 5862 HValue* value = Pop();
5833 Literal* literal = expr->right()->AsLiteral(); 5863 Literal* literal = expr->right()->AsLiteral();
5834 Handle<String> rhs = Handle<String>::cast(literal->handle()); 5864 Handle<String> rhs = Handle<String>::cast(literal->handle());
5835 HClassOfTestAndBranch* instr = 5865 HClassOfTestAndBranch* instr =
5836 new(zone()) HClassOfTestAndBranch(value, rhs); 5866 new(zone()) HClassOfTestAndBranch(value, rhs);
5837 instr->set_position(expr->position()); 5867 instr->set_position(expr->position());
5838 return ast_context()->ReturnControl(instr, expr->id()); 5868 return ast_context()->ReturnControl(instr, expr->id());
5839 } 5869 }
5840 5870
5841 // Check for special cases that compare against literals.
5842 if (TryLiteralCompare(expr)) return;
5843
5844 TypeInfo type_info = oracle()->CompareType(expr); 5871 TypeInfo type_info = oracle()->CompareType(expr);
5845 // Check if this expression was ever executed according to type feedback. 5872 // Check if this expression was ever executed according to type feedback.
5873 // Note that for the special typeof/null/undefined cases we get unknown here.
5846 if (type_info.IsUninitialized()) { 5874 if (type_info.IsUninitialized()) {
5847 AddInstruction(new(zone()) HSoftDeoptimize); 5875 AddInstruction(new(zone()) HSoftDeoptimize);
5848 current_block()->MarkAsDeoptimizing(); 5876 current_block()->MarkAsDeoptimizing();
5849 type_info = TypeInfo::Unknown(); 5877 type_info = TypeInfo::Unknown();
5850 } 5878 }
5851 5879
5852 CHECK_ALIVE(VisitForValue(expr->left())); 5880 CHECK_ALIVE(VisitForValue(expr->left()));
5853 CHECK_ALIVE(VisitForValue(expr->right())); 5881 CHECK_ALIVE(VisitForValue(expr->right()));
5854 5882
5855 HValue* context = environment()->LookupContext(); 5883 HValue* context = environment()->LookupContext();
5856 HValue* right = Pop(); 5884 HValue* right = Pop();
5857 HValue* left = Pop(); 5885 HValue* left = Pop();
5858 Token::Value op = expr->op(); 5886 Token::Value op = expr->op();
5859 5887
5888 HTypeof* typeof_expr = NULL;
5889 Handle<String> check;
5890 if (IsLiteralCompareTypeof(left, op, right, &typeof_expr, &check)) {
5891 return HandleLiteralCompareTypeof(expr, typeof_expr, check);
5892 }
5893 HValue* sub_expr = NULL;
5894 Factory* f = graph()->isolate()->factory();
5895 if (IsLiteralCompareNil(left, op, right, f->undefined_value(), &sub_expr)) {
5896 return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
5897 }
5898 if (IsLiteralCompareNil(left, op, right, f->null_value(), &sub_expr)) {
5899 return HandleLiteralCompareNil(expr, sub_expr, kNullValue);
5900 }
5901
5860 if (op == Token::INSTANCEOF) { 5902 if (op == Token::INSTANCEOF) {
5861 // Check to see if the rhs of the instanceof is a global function not 5903 // Check to see if the rhs of the instanceof is a global function not
5862 // residing in new space. If it is we assume that the function will stay the 5904 // residing in new space. If it is we assume that the function will stay the
5863 // same. 5905 // same.
5864 Handle<JSFunction> target = Handle<JSFunction>::null(); 5906 Handle<JSFunction> target = Handle<JSFunction>::null();
5865 VariableProxy* proxy = expr->right()->AsVariableProxy(); 5907 VariableProxy* proxy = expr->right()->AsVariableProxy();
5866 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); 5908 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated();
5867 if (global_function && 5909 if (global_function &&
5868 info()->has_global_object() && 5910 info()->has_global_object() &&
5869 !info()->global_object()->IsAccessCheckNeeded()) { 5911 !info()->global_object()->IsAccessCheckNeeded()) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
5938 new(zone()) HCompareIDAndBranch(left, right, op); 5980 new(zone()) HCompareIDAndBranch(left, right, op);
5939 result->set_position(expr->position()); 5981 result->set_position(expr->position());
5940 result->SetInputRepresentation(r); 5982 result->SetInputRepresentation(r);
5941 return ast_context()->ReturnControl(result, expr->id()); 5983 return ast_context()->ReturnControl(result, expr->id());
5942 } 5984 }
5943 } 5985 }
5944 } 5986 }
5945 5987
5946 5988
5947 void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 5989 void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
5948 Expression* sub_expr, 5990 HValue* value,
5949 NilValue nil) { 5991 NilValue nil) {
5950 ASSERT(!HasStackOverflow()); 5992 ASSERT(!HasStackOverflow());
5951 ASSERT(current_block() != NULL); 5993 ASSERT(current_block() != NULL);
5952 ASSERT(current_block()->HasPredecessor()); 5994 ASSERT(current_block()->HasPredecessor());
5953 CHECK_ALIVE(VisitForValue(sub_expr));
5954 HValue* value = Pop();
5955 EqualityKind kind = 5995 EqualityKind kind =
5956 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; 5996 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality;
5957 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil); 5997 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil);
5958 instr->set_position(expr->position()); 5998 instr->set_position(expr->position());
5959 return ast_context()->ReturnControl(instr, expr->id()); 5999 return ast_context()->ReturnControl(instr, expr->id());
5960 } 6000 }
5961 6001
5962 6002
5963 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { 6003 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
5964 ASSERT(!HasStackOverflow()); 6004 ASSERT(!HasStackOverflow());
(...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after
6937 } 6977 }
6938 } 6978 }
6939 6979
6940 #ifdef DEBUG 6980 #ifdef DEBUG
6941 if (graph_ != NULL) graph_->Verify(false); // No full verify. 6981 if (graph_ != NULL) graph_->Verify(false); // No full verify.
6942 if (allocator_ != NULL) allocator_->Verify(); 6982 if (allocator_ != NULL) allocator_->Verify();
6943 #endif 6983 #endif
6944 } 6984 }
6945 6985
6946 } } // namespace v8::internal 6986 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698