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 5772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |