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