| OLD | NEW |
| 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 Loading... |
| 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 HTypeof* typeof_expr, | 5792 Expression* sub_expr, |
| 5793 Handle<String> check) { | 5793 Handle<String> check) { |
| 5794 HValue* value = typeof_expr->value(); | 5794 CHECK_ALIVE(VisitForTypeOf(sub_expr)); |
| 5795 HValue* value = Pop(); |
| 5795 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); | 5796 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); |
| 5796 instr->set_position(expr->position()); | 5797 instr->set_position(expr->position()); |
| 5797 ast_context()->ReturnControl(instr, expr->id()); | 5798 return ast_context()->ReturnControl(instr, expr->id()); |
| 5798 typeof_expr->DeleteAndReplaceWith(NULL); | |
| 5799 } | 5799 } |
| 5800 | 5800 |
| 5801 | 5801 |
| 5802 static bool MatchLiteralCompareNil(HValue* left, | 5802 bool HGraphBuilder::TryLiteralCompare(CompareOperation* expr) { |
| 5803 Token::Value op, | 5803 Expression *sub_expr; |
| 5804 HValue* right, | 5804 Handle<String> check; |
| 5805 Handle<Object> nil, | 5805 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { |
| 5806 HValue** expr) { | 5806 HandleLiteralCompareTypeof(expr, sub_expr, check); |
| 5807 if (left->IsConstant() && | |
| 5808 HConstant::cast(left)->handle().is_identical_to(nil) && | |
| 5809 Token::IsEqualityOp(op)) { | |
| 5810 *expr = right; | |
| 5811 return true; | 5807 return true; |
| 5812 } | 5808 } |
| 5813 return false; | |
| 5814 } | |
| 5815 | 5809 |
| 5816 | 5810 if (expr->IsLiteralCompareUndefined(&sub_expr)) { |
| 5817 static bool MatchLiteralCompareTypeof(HValue* left, | 5811 HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); |
| 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()); | |
| 5828 return true; | 5812 return true; |
| 5829 } | 5813 } |
| 5814 |
| 5815 if (expr->IsLiteralCompareNull(&sub_expr)) { |
| 5816 HandleLiteralCompareNil(expr, sub_expr, kNullValue); |
| 5817 return true; |
| 5818 } |
| 5819 |
| 5830 return false; | 5820 return false; |
| 5831 } | 5821 } |
| 5832 | 5822 |
| 5833 | 5823 |
| 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); | |
| 5851 } | |
| 5852 | |
| 5853 | |
| 5854 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 5824 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
| 5855 ASSERT(!HasStackOverflow()); | 5825 ASSERT(!HasStackOverflow()); |
| 5856 ASSERT(current_block() != NULL); | 5826 ASSERT(current_block() != NULL); |
| 5857 ASSERT(current_block()->HasPredecessor()); | 5827 ASSERT(current_block()->HasPredecessor()); |
| 5858 if (IsClassOfTest(expr)) { | 5828 if (IsClassOfTest(expr)) { |
| 5859 CallRuntime* call = expr->left()->AsCallRuntime(); | 5829 CallRuntime* call = expr->left()->AsCallRuntime(); |
| 5860 ASSERT(call->arguments()->length() == 1); | 5830 ASSERT(call->arguments()->length() == 1); |
| 5861 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5831 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 5862 HValue* value = Pop(); | 5832 HValue* value = Pop(); |
| 5863 Literal* literal = expr->right()->AsLiteral(); | 5833 Literal* literal = expr->right()->AsLiteral(); |
| 5864 Handle<String> rhs = Handle<String>::cast(literal->handle()); | 5834 Handle<String> rhs = Handle<String>::cast(literal->handle()); |
| 5865 HClassOfTestAndBranch* instr = | 5835 HClassOfTestAndBranch* instr = |
| 5866 new(zone()) HClassOfTestAndBranch(value, rhs); | 5836 new(zone()) HClassOfTestAndBranch(value, rhs); |
| 5867 instr->set_position(expr->position()); | 5837 instr->set_position(expr->position()); |
| 5868 return ast_context()->ReturnControl(instr, expr->id()); | 5838 return ast_context()->ReturnControl(instr, expr->id()); |
| 5869 } | 5839 } |
| 5870 | 5840 |
| 5841 // Check for special cases that compare against literals. |
| 5842 if (TryLiteralCompare(expr)) return; |
| 5843 |
| 5871 TypeInfo type_info = oracle()->CompareType(expr); | 5844 TypeInfo type_info = oracle()->CompareType(expr); |
| 5872 // Check if this expression was ever executed according to type feedback. | 5845 // 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. | |
| 5874 if (type_info.IsUninitialized()) { | 5846 if (type_info.IsUninitialized()) { |
| 5875 AddInstruction(new(zone()) HSoftDeoptimize); | 5847 AddInstruction(new(zone()) HSoftDeoptimize); |
| 5876 current_block()->MarkAsDeoptimizing(); | 5848 current_block()->MarkAsDeoptimizing(); |
| 5877 type_info = TypeInfo::Unknown(); | 5849 type_info = TypeInfo::Unknown(); |
| 5878 } | 5850 } |
| 5879 | 5851 |
| 5880 CHECK_ALIVE(VisitForValue(expr->left())); | 5852 CHECK_ALIVE(VisitForValue(expr->left())); |
| 5881 CHECK_ALIVE(VisitForValue(expr->right())); | 5853 CHECK_ALIVE(VisitForValue(expr->right())); |
| 5882 | 5854 |
| 5883 HValue* context = environment()->LookupContext(); | 5855 HValue* context = environment()->LookupContext(); |
| 5884 HValue* right = Pop(); | 5856 HValue* right = Pop(); |
| 5885 HValue* left = Pop(); | 5857 HValue* left = Pop(); |
| 5886 Token::Value op = expr->op(); | 5858 Token::Value op = expr->op(); |
| 5887 | 5859 |
| 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 | |
| 5902 if (op == Token::INSTANCEOF) { | 5860 if (op == Token::INSTANCEOF) { |
| 5903 // Check to see if the rhs of the instanceof is a global function not | 5861 // Check to see if the rhs of the instanceof is a global function not |
| 5904 // residing in new space. If it is we assume that the function will stay the | 5862 // residing in new space. If it is we assume that the function will stay the |
| 5905 // same. | 5863 // same. |
| 5906 Handle<JSFunction> target = Handle<JSFunction>::null(); | 5864 Handle<JSFunction> target = Handle<JSFunction>::null(); |
| 5907 VariableProxy* proxy = expr->right()->AsVariableProxy(); | 5865 VariableProxy* proxy = expr->right()->AsVariableProxy(); |
| 5908 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); | 5866 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); |
| 5909 if (global_function && | 5867 if (global_function && |
| 5910 info()->has_global_object() && | 5868 info()->has_global_object() && |
| 5911 !info()->global_object()->IsAccessCheckNeeded()) { | 5869 !info()->global_object()->IsAccessCheckNeeded()) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5980 new(zone()) HCompareIDAndBranch(left, right, op); | 5938 new(zone()) HCompareIDAndBranch(left, right, op); |
| 5981 result->set_position(expr->position()); | 5939 result->set_position(expr->position()); |
| 5982 result->SetInputRepresentation(r); | 5940 result->SetInputRepresentation(r); |
| 5983 return ast_context()->ReturnControl(result, expr->id()); | 5941 return ast_context()->ReturnControl(result, expr->id()); |
| 5984 } | 5942 } |
| 5985 } | 5943 } |
| 5986 } | 5944 } |
| 5987 | 5945 |
| 5988 | 5946 |
| 5989 void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 5947 void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
| 5990 HValue* value, | 5948 Expression* sub_expr, |
| 5991 NilValue nil) { | 5949 NilValue nil) { |
| 5992 ASSERT(!HasStackOverflow()); | 5950 ASSERT(!HasStackOverflow()); |
| 5993 ASSERT(current_block() != NULL); | 5951 ASSERT(current_block() != NULL); |
| 5994 ASSERT(current_block()->HasPredecessor()); | 5952 ASSERT(current_block()->HasPredecessor()); |
| 5953 CHECK_ALIVE(VisitForValue(sub_expr)); |
| 5954 HValue* value = Pop(); |
| 5995 EqualityKind kind = | 5955 EqualityKind kind = |
| 5996 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; | 5956 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; |
| 5997 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil); | 5957 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil); |
| 5998 instr->set_position(expr->position()); | 5958 instr->set_position(expr->position()); |
| 5999 return ast_context()->ReturnControl(instr, expr->id()); | 5959 return ast_context()->ReturnControl(instr, expr->id()); |
| 6000 } | 5960 } |
| 6001 | 5961 |
| 6002 | 5962 |
| 6003 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 5963 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
| 6004 ASSERT(!HasStackOverflow()); | 5964 ASSERT(!HasStackOverflow()); |
| (...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6977 } | 6937 } |
| 6978 } | 6938 } |
| 6979 | 6939 |
| 6980 #ifdef DEBUG | 6940 #ifdef DEBUG |
| 6981 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 6941 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 6982 if (allocator_ != NULL) allocator_->Verify(); | 6942 if (allocator_ != NULL) allocator_->Verify(); |
| 6983 #endif | 6943 #endif |
| 6984 } | 6944 } |
| 6985 | 6945 |
| 6986 } } // namespace v8::internal | 6946 } } // namespace v8::internal |
| OLD | NEW |