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

Side by Side Diff: src/hydrogen.cc

Issue 17468003: Use AST's type field and merge types for unary, binary & compare ICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comments Created 7 years, 6 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
« no previous file with comments | « src/globals.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/globals.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698