OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 9013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9024 return ast_context()->ReturnInstruction(instr, expr->id()); | 9024 return ast_context()->ReturnInstruction(instr, expr->id()); |
9025 } | 9025 } |
9026 | 9026 |
9027 | 9027 |
9028 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { | 9028 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { |
9029 CHECK_ALIVE(VisitForValue(expr->expression())); | 9029 CHECK_ALIVE(VisitForValue(expr->expression())); |
9030 HValue* value = Pop(); | 9030 HValue* value = Pop(); |
9031 HValue* context = environment()->LookupContext(); | 9031 HValue* context = environment()->LookupContext(); |
9032 HInstruction* instr = | 9032 HInstruction* instr = |
9033 HMul::New(zone(), context, value, graph()->GetConstantMinus1()); | 9033 HMul::New(zone(), context, value, graph()->GetConstantMinus1()); |
9034 Handle<Type> type = expr->type(); | 9034 Handle<Type> operand_type = expr->expression()->lower_type(); |
9035 Representation rep = ToRepresentation(type); | 9035 Representation rep = ToRepresentation(operand_type); |
9036 if (type->Is(Type::None())) { | 9036 if (operand_type->Is(Type::None())) { |
9037 AddSoftDeoptimize(); | 9037 AddSoftDeoptimize(); |
9038 type = handle(Type::Any(), isolate()); | |
9039 } | 9038 } |
9040 if (instr->IsBinaryOperation()) { | 9039 if (instr->IsBinaryOperation()) { |
9041 HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep); | 9040 HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep); |
9042 HBinaryOperation::cast(instr)->set_observed_input_representation(2, rep); | 9041 HBinaryOperation::cast(instr)->set_observed_input_representation(2, rep); |
9043 } | 9042 } |
9044 return ast_context()->ReturnInstruction(instr, expr->id()); | 9043 return ast_context()->ReturnInstruction(instr, expr->id()); |
9045 } | 9044 } |
9046 | 9045 |
9047 | 9046 |
9048 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { | 9047 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { |
9049 CHECK_ALIVE(VisitForValue(expr->expression())); | 9048 CHECK_ALIVE(VisitForValue(expr->expression())); |
9050 HValue* value = Pop(); | 9049 HValue* value = Pop(); |
9051 Handle<Type> info = expr->type(); | 9050 Handle<Type> operand_type = expr->expression()->lower_type(); |
9052 if (info->Is(Type::None())) { | 9051 if (operand_type->Is(Type::None())) { |
9053 AddSoftDeoptimize(); | 9052 AddSoftDeoptimize(); |
9054 } | 9053 } |
9055 HInstruction* instr = new(zone()) HBitNot(value); | 9054 HInstruction* instr = new(zone()) HBitNot(value); |
9056 return ast_context()->ReturnInstruction(instr, expr->id()); | 9055 return ast_context()->ReturnInstruction(instr, expr->id()); |
9057 } | 9056 } |
9058 | 9057 |
9059 | 9058 |
9060 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { | 9059 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { |
9061 if (ast_context()->IsTest()) { | 9060 if (ast_context()->IsTest()) { |
9062 TestContext* context = TestContext::cast(ast_context()); | 9061 TestContext* context = TestContext::cast(ast_context()); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9404 } | 9403 } |
9405 return true; | 9404 return true; |
9406 } | 9405 } |
9407 | 9406 |
9408 | 9407 |
9409 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( | 9408 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( |
9410 BinaryOperation* expr, | 9409 BinaryOperation* expr, |
9411 HValue* left, | 9410 HValue* left, |
9412 HValue* right) { | 9411 HValue* right) { |
9413 HValue* context = environment()->LookupContext(); | 9412 HValue* context = environment()->LookupContext(); |
9414 Handle<Type> left_type = expr->left_type(); | 9413 Handle<Type> left_type = expr->left()->lower_type(); |
9415 Handle<Type> right_type = expr->right_type(); | 9414 Handle<Type> right_type = expr->right()->lower_type(); |
9416 Handle<Type> result_type = expr->result_type(); | 9415 Handle<Type> result_type = expr->result_type(); |
9417 bool has_fixed_right_arg = expr->has_fixed_right_arg(); | 9416 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
9418 int fixed_right_arg_value = expr->fixed_right_arg_value(); | |
9419 Representation left_rep = ToRepresentation(left_type); | 9417 Representation left_rep = ToRepresentation(left_type); |
9420 Representation right_rep = ToRepresentation(right_type); | 9418 Representation right_rep = ToRepresentation(right_type); |
9421 Representation result_rep = ToRepresentation(result_type); | 9419 Representation result_rep = ToRepresentation(result_type); |
9422 if (left_type->Is(Type::None())) { | 9420 if (left_type->Is(Type::None())) { |
9423 AddSoftDeoptimize(); | 9421 AddSoftDeoptimize(); |
| 9422 // TODO(rossberg): we should be able to get rid of non-continuous defaults. |
9424 left_type = handle(Type::Any(), isolate()); | 9423 left_type = handle(Type::Any(), isolate()); |
9425 } | 9424 } |
9426 if (right_type->Is(Type::None())) { | 9425 if (right_type->Is(Type::None())) { |
9427 AddSoftDeoptimize(); | 9426 AddSoftDeoptimize(); |
9428 right_type = handle(Type::Any(), isolate()); | 9427 right_type = handle(Type::Any(), isolate()); |
9429 } | 9428 } |
9430 HInstruction* instr = NULL; | 9429 HInstruction* instr = NULL; |
9431 switch (expr->op()) { | 9430 switch (expr->op()) { |
9432 case Token::ADD: | 9431 case Token::ADD: |
9433 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { | 9432 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { |
9434 BuildCheckNonSmi(left); | 9433 BuildCheckNonSmi(left); |
9435 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 9434 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
9436 BuildCheckNonSmi(right); | 9435 BuildCheckNonSmi(right); |
9437 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 9436 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
9438 instr = HStringAdd::New(zone(), context, left, right); | 9437 instr = HStringAdd::New(zone(), context, left, right); |
9439 } else { | 9438 } else { |
9440 instr = HAdd::New(zone(), context, left, right); | 9439 instr = HAdd::New(zone(), context, left, right); |
9441 } | 9440 } |
9442 break; | 9441 break; |
9443 case Token::SUB: | 9442 case Token::SUB: |
9444 instr = HSub::New(zone(), context, left, right); | 9443 instr = HSub::New(zone(), context, left, right); |
9445 break; | 9444 break; |
9446 case Token::MUL: | 9445 case Token::MUL: |
9447 instr = HMul::New(zone(), context, left, right); | 9446 instr = HMul::New(zone(), context, left, right); |
9448 break; | 9447 break; |
9449 case Token::MOD: | 9448 case Token::MOD: |
9450 instr = HMod::New(zone(), | 9449 instr = HMod::New(zone(), context, left, right, fixed_right_arg); |
9451 context, | |
9452 left, | |
9453 right, | |
9454 has_fixed_right_arg, | |
9455 fixed_right_arg_value); | |
9456 break; | 9450 break; |
9457 case Token::DIV: | 9451 case Token::DIV: |
9458 instr = HDiv::New(zone(), context, left, right); | 9452 instr = HDiv::New(zone(), context, left, right); |
9459 break; | 9453 break; |
9460 case Token::BIT_XOR: | 9454 case Token::BIT_XOR: |
9461 case Token::BIT_AND: | 9455 case Token::BIT_AND: |
9462 instr = HBitwise::New(zone(), expr->op(), context, left, right); | 9456 instr = HBitwise::New(zone(), expr->op(), context, left, right); |
9463 break; | 9457 break; |
9464 case Token::BIT_OR: { | 9458 case Token::BIT_OR: { |
9465 HValue* operand, *shift_amount; | 9459 HValue* operand, *shift_amount; |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9752 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9746 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9753 HValue* value = Pop(); | 9747 HValue* value = Pop(); |
9754 Literal* literal = expr->right()->AsLiteral(); | 9748 Literal* literal = expr->right()->AsLiteral(); |
9755 Handle<String> rhs = Handle<String>::cast(literal->handle()); | 9749 Handle<String> rhs = Handle<String>::cast(literal->handle()); |
9756 HClassOfTestAndBranch* instr = | 9750 HClassOfTestAndBranch* instr = |
9757 new(zone()) HClassOfTestAndBranch(value, rhs); | 9751 new(zone()) HClassOfTestAndBranch(value, rhs); |
9758 instr->set_position(expr->position()); | 9752 instr->set_position(expr->position()); |
9759 return ast_context()->ReturnControl(instr, expr->id()); | 9753 return ast_context()->ReturnControl(instr, expr->id()); |
9760 } | 9754 } |
9761 | 9755 |
9762 Handle<Type> left_type = expr->left_type(); | 9756 Handle<Type> left_type = expr->left()->lower_type(); |
9763 Handle<Type> right_type = expr->right_type(); | 9757 Handle<Type> right_type = expr->right()->lower_type(); |
9764 Handle<Type> overall_type = expr->overall_type(); | 9758 Handle<Type> combined_type = expr->combined_type(); |
9765 Representation combined_rep = ToRepresentation(overall_type); | 9759 Representation combined_rep = ToRepresentation(combined_type); |
9766 Representation left_rep = ToRepresentation(left_type); | 9760 Representation left_rep = ToRepresentation(left_type); |
9767 Representation right_rep = ToRepresentation(right_type); | 9761 Representation right_rep = ToRepresentation(right_type); |
9768 // Check if this expression was ever executed according to type feedback. | 9762 // Check if this expression was ever executed according to type feedback. |
9769 // Note that for the special typeof/null/undefined cases we get unknown here. | 9763 // Note that for the special typeof/null/undefined cases we get unknown here. |
9770 if (overall_type->Is(Type::None())) { | 9764 if (combined_type->Is(Type::None())) { |
9771 AddSoftDeoptimize(); | 9765 AddSoftDeoptimize(); |
9772 overall_type = left_type = right_type = handle(Type::Any(), isolate()); | 9766 combined_type = left_type = right_type = handle(Type::Any(), isolate()); |
9773 } | 9767 } |
9774 | 9768 |
9775 CHECK_ALIVE(VisitForValue(expr->left())); | 9769 CHECK_ALIVE(VisitForValue(expr->left())); |
9776 CHECK_ALIVE(VisitForValue(expr->right())); | 9770 CHECK_ALIVE(VisitForValue(expr->right())); |
9777 | 9771 |
9778 HValue* context = environment()->LookupContext(); | 9772 HValue* context = environment()->LookupContext(); |
9779 HValue* right = Pop(); | 9773 HValue* right = Pop(); |
9780 HValue* left = Pop(); | 9774 HValue* left = Pop(); |
9781 Token::Value op = expr->op(); | 9775 Token::Value op = expr->op(); |
9782 | 9776 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9834 AddInstruction(new(zone()) HCheckFunction(right, target)); | 9828 AddInstruction(new(zone()) HCheckFunction(right, target)); |
9835 HInstanceOfKnownGlobal* result = | 9829 HInstanceOfKnownGlobal* result = |
9836 new(zone()) HInstanceOfKnownGlobal(context, left, target); | 9830 new(zone()) HInstanceOfKnownGlobal(context, left, target); |
9837 result->set_position(expr->position()); | 9831 result->set_position(expr->position()); |
9838 return ast_context()->ReturnInstruction(result, expr->id()); | 9832 return ast_context()->ReturnInstruction(result, expr->id()); |
9839 } | 9833 } |
9840 } else if (op == Token::IN) { | 9834 } else if (op == Token::IN) { |
9841 HIn* result = new(zone()) HIn(context, left, right); | 9835 HIn* result = new(zone()) HIn(context, left, right); |
9842 result->set_position(expr->position()); | 9836 result->set_position(expr->position()); |
9843 return ast_context()->ReturnInstruction(result, expr->id()); | 9837 return ast_context()->ReturnInstruction(result, expr->id()); |
9844 } else if (overall_type->Is(Type::Receiver())) { | 9838 } else if (combined_type->Is(Type::Receiver())) { |
9845 switch (op) { | 9839 switch (op) { |
9846 case Token::EQ: | 9840 case Token::EQ: |
9847 case Token::EQ_STRICT: { | 9841 case Token::EQ_STRICT: { |
9848 // Can we get away with map check and not instance type check? | 9842 // Can we get away with map check and not instance type check? |
9849 if (overall_type->IsClass()) { | 9843 if (combined_type->IsClass()) { |
9850 Handle<Map> map = overall_type->AsClass(); | 9844 Handle<Map> map = combined_type->AsClass(); |
9851 AddCheckMapsWithTransitions(left, map); | 9845 AddCheckMapsWithTransitions(left, map); |
9852 AddCheckMapsWithTransitions(right, map); | 9846 AddCheckMapsWithTransitions(right, map); |
9853 HCompareObjectEqAndBranch* result = | 9847 HCompareObjectEqAndBranch* result = |
9854 new(zone()) HCompareObjectEqAndBranch(left, right); | 9848 new(zone()) HCompareObjectEqAndBranch(left, right); |
9855 result->set_position(expr->position()); | 9849 result->set_position(expr->position()); |
9856 return ast_context()->ReturnControl(result, expr->id()); | 9850 return ast_context()->ReturnControl(result, expr->id()); |
9857 } else { | 9851 } else { |
9858 BuildCheckNonSmi(left); | 9852 BuildCheckNonSmi(left); |
9859 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); | 9853 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
9860 BuildCheckNonSmi(right); | 9854 BuildCheckNonSmi(right); |
9861 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); | 9855 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
9862 HCompareObjectEqAndBranch* result = | 9856 HCompareObjectEqAndBranch* result = |
9863 new(zone()) HCompareObjectEqAndBranch(left, right); | 9857 new(zone()) HCompareObjectEqAndBranch(left, right); |
9864 result->set_position(expr->position()); | 9858 result->set_position(expr->position()); |
9865 return ast_context()->ReturnControl(result, expr->id()); | 9859 return ast_context()->ReturnControl(result, expr->id()); |
9866 } | 9860 } |
9867 } | 9861 } |
9868 default: | 9862 default: |
9869 return Bailout("Unsupported non-primitive compare"); | 9863 return Bailout("Unsupported non-primitive compare"); |
9870 } | 9864 } |
9871 } else if (overall_type->Is(Type::InternalizedString()) && | 9865 } else if (combined_type->Is(Type::InternalizedString()) && |
9872 Token::IsEqualityOp(op)) { | 9866 Token::IsEqualityOp(op)) { |
9873 BuildCheckNonSmi(left); | 9867 BuildCheckNonSmi(left); |
9874 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); | 9868 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); |
9875 BuildCheckNonSmi(right); | 9869 BuildCheckNonSmi(right); |
9876 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); | 9870 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); |
9877 HCompareObjectEqAndBranch* result = | 9871 HCompareObjectEqAndBranch* result = |
9878 new(zone()) HCompareObjectEqAndBranch(left, right); | 9872 new(zone()) HCompareObjectEqAndBranch(left, right); |
9879 result->set_position(expr->position()); | 9873 result->set_position(expr->position()); |
9880 return ast_context()->ReturnControl(result, expr->id()); | 9874 return ast_context()->ReturnControl(result, expr->id()); |
9881 } else { | 9875 } else { |
(...skipping 30 matching lines...) Expand all Loading... |
9912 if (expr->op() == Token::EQ_STRICT) { | 9906 if (expr->op() == Token::EQ_STRICT) { |
9913 IfBuilder if_nil(this); | 9907 IfBuilder if_nil(this); |
9914 if_nil.If<HCompareObjectEqAndBranch>( | 9908 if_nil.If<HCompareObjectEqAndBranch>( |
9915 value, (nil == kNullValue) ? graph()->GetConstantNull() | 9909 value, (nil == kNullValue) ? graph()->GetConstantNull() |
9916 : graph()->GetConstantUndefined()); | 9910 : graph()->GetConstantUndefined()); |
9917 if_nil.Then(); | 9911 if_nil.Then(); |
9918 if_nil.Else(); | 9912 if_nil.Else(); |
9919 if_nil.CaptureContinuation(&continuation); | 9913 if_nil.CaptureContinuation(&continuation); |
9920 return ast_context()->ReturnContinuation(&continuation, expr->id()); | 9914 return ast_context()->ReturnContinuation(&continuation, expr->id()); |
9921 } | 9915 } |
9922 Handle<Type> type = expr->compare_nil_type()->Is(Type::None()) | 9916 Handle<Type> type = expr->combined_type()->Is(Type::None()) |
9923 ? handle(Type::Any(), isolate_) : expr->compare_nil_type(); | 9917 ? handle(Type::Any(), isolate_) : expr->combined_type(); |
9924 BuildCompareNil(value, type, expr->position(), &continuation); | 9918 BuildCompareNil(value, type, expr->position(), &continuation); |
9925 return ast_context()->ReturnContinuation(&continuation, expr->id()); | 9919 return ast_context()->ReturnContinuation(&continuation, expr->id()); |
9926 } | 9920 } |
9927 | 9921 |
9928 | 9922 |
9929 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { | 9923 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { |
9930 // If we share optimized code between different closures, the | 9924 // If we share optimized code between different closures, the |
9931 // this-function is not a constant, except inside an inlined body. | 9925 // this-function is not a constant, except inside an inlined body. |
9932 if (function_state()->outer() != NULL) { | 9926 if (function_state()->outer() != NULL) { |
9933 return new(zone()) HConstant( | 9927 return new(zone()) HConstant( |
(...skipping 1650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11584 } | 11578 } |
11585 } | 11579 } |
11586 | 11580 |
11587 #ifdef DEBUG | 11581 #ifdef DEBUG |
11588 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11582 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11589 if (allocator_ != NULL) allocator_->Verify(); | 11583 if (allocator_ != NULL) allocator_->Verify(); |
11590 #endif | 11584 #endif |
11591 } | 11585 } |
11592 | 11586 |
11593 } } // namespace v8::internal | 11587 } } // namespace v8::internal |
OLD | NEW |