Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 3043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3054 set_current_block(body_entry); | 3054 set_current_block(body_entry); |
| 3055 | 3055 |
| 3056 // Handle implicit declaration of the function name in named function | 3056 // Handle implicit declaration of the function name in named function |
| 3057 // expressions before other declarations. | 3057 // expressions before other declarations. |
| 3058 if (scope->is_function_scope() && scope->function() != NULL) { | 3058 if (scope->is_function_scope() && scope->function() != NULL) { |
| 3059 VisitVariableDeclaration(scope->function()); | 3059 VisitVariableDeclaration(scope->function()); |
| 3060 } | 3060 } |
| 3061 VisitDeclarations(scope->declarations()); | 3061 VisitDeclarations(scope->declarations()); |
| 3062 Add<HSimulate>(BailoutId::Declarations()); | 3062 Add<HSimulate>(BailoutId::Declarations()); |
| 3063 | 3063 |
| 3064 HValue* context = environment()->context(); | 3064 Add<HStackCheck>(HStackCheck::kFunctionEntry); |
| 3065 Add<HStackCheck>(context, HStackCheck::kFunctionEntry); | |
| 3066 | 3065 |
| 3067 VisitStatements(current_info()->function()->body()); | 3066 VisitStatements(current_info()->function()->body()); |
| 3068 if (HasStackOverflow()) return false; | 3067 if (HasStackOverflow()) return false; |
| 3069 | 3068 |
| 3070 if (current_block() != NULL) { | 3069 if (current_block() != NULL) { |
| 3071 Add<HReturn>(graph()->GetConstantUndefined()); | 3070 Add<HReturn>(graph()->GetConstantUndefined()); |
| 3072 set_current_block(NULL); | 3071 set_current_block(NULL); |
| 3073 } | 3072 } |
| 3074 | 3073 |
| 3075 // If the checksum of the number of type info changes is the same as the | 3074 // If the checksum of the number of type info changes is the same as the |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3511 int clause_count = clauses->length(); | 3510 int clause_count = clauses->length(); |
| 3512 if (clause_count > kCaseClauseLimit) { | 3511 if (clause_count > kCaseClauseLimit) { |
| 3513 return Bailout(kSwitchStatementTooManyClauses); | 3512 return Bailout(kSwitchStatementTooManyClauses); |
| 3514 } | 3513 } |
| 3515 | 3514 |
| 3516 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); | 3515 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); |
| 3517 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { | 3516 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { |
| 3518 return Bailout(kSwitchStatementMixedOrNonLiteralSwitchLabels); | 3517 return Bailout(kSwitchStatementMixedOrNonLiteralSwitchLabels); |
| 3519 } | 3518 } |
| 3520 | 3519 |
| 3521 HValue* context = environment()->context(); | |
| 3522 | |
| 3523 CHECK_ALIVE(VisitForValue(stmt->tag())); | 3520 CHECK_ALIVE(VisitForValue(stmt->tag())); |
| 3524 Add<HSimulate>(stmt->EntryId()); | 3521 Add<HSimulate>(stmt->EntryId()); |
| 3525 HValue* tag_value = Pop(); | 3522 HValue* tag_value = Pop(); |
| 3526 HBasicBlock* first_test_block = current_block(); | 3523 HBasicBlock* first_test_block = current_block(); |
| 3527 | 3524 |
| 3528 HUnaryControlInstruction* string_check = NULL; | 3525 HUnaryControlInstruction* string_check = NULL; |
| 3529 HBasicBlock* not_string_block = NULL; | 3526 HBasicBlock* not_string_block = NULL; |
| 3530 | 3527 |
| 3531 // Test switch's tag value if all clauses are string literals | 3528 // Test switch's tag value if all clauses are string literals |
| 3532 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) { | 3529 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 3563 } | 3560 } |
| 3564 | 3561 |
| 3565 HCompareNumericAndBranch* compare_ = | 3562 HCompareNumericAndBranch* compare_ = |
| 3566 New<HCompareNumericAndBranch>(tag_value, | 3563 New<HCompareNumericAndBranch>(tag_value, |
| 3567 label_value, | 3564 label_value, |
| 3568 Token::EQ_STRICT); | 3565 Token::EQ_STRICT); |
| 3569 compare_->set_observed_input_representation( | 3566 compare_->set_observed_input_representation( |
| 3570 Representation::Smi(), Representation::Smi()); | 3567 Representation::Smi(), Representation::Smi()); |
| 3571 compare = compare_; | 3568 compare = compare_; |
| 3572 } else { | 3569 } else { |
| 3573 compare = new(zone()) HStringCompareAndBranch(context, tag_value, | 3570 compare = New<HStringCompareAndBranch>(tag_value, |
| 3574 label_value, | 3571 label_value, |
| 3575 Token::EQ_STRICT); | 3572 Token::EQ_STRICT); |
| 3576 } | 3573 } |
| 3577 | 3574 |
| 3578 compare->SetSuccessorAt(0, body_block); | 3575 compare->SetSuccessorAt(0, body_block); |
| 3579 compare->SetSuccessorAt(1, next_test_block); | 3576 compare->SetSuccessorAt(1, next_test_block); |
| 3580 current_block()->Finish(compare); | 3577 current_block()->Finish(compare); |
| 3581 | 3578 |
| 3582 set_current_block(next_test_block); | 3579 set_current_block(next_test_block); |
| 3583 } | 3580 } |
| 3584 | 3581 |
| 3585 // Save the current block to use for the default or to join with the | 3582 // Save the current block to use for the default or to join with the |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3657 set_current_block(break_block); | 3654 set_current_block(break_block); |
| 3658 } | 3655 } |
| 3659 } | 3656 } |
| 3660 | 3657 |
| 3661 | 3658 |
| 3662 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, | 3659 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
| 3663 HBasicBlock* loop_entry, | 3660 HBasicBlock* loop_entry, |
| 3664 BreakAndContinueInfo* break_info) { | 3661 BreakAndContinueInfo* break_info) { |
| 3665 BreakAndContinueScope push(break_info, this); | 3662 BreakAndContinueScope push(break_info, this); |
| 3666 Add<HSimulate>(stmt->StackCheckId()); | 3663 Add<HSimulate>(stmt->StackCheckId()); |
| 3667 HValue* context = environment()->context(); | 3664 HStackCheck* stack_check = |
| 3668 HStackCheck* stack_check = HStackCheck::cast(Add<HStackCheck>( | 3665 HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); |
|
danno
2013/09/25 11:44:28
nit: four indentation spaces
| |
| 3669 context, HStackCheck::kBackwardsBranch)); | |
| 3670 ASSERT(loop_entry->IsLoopHeader()); | 3666 ASSERT(loop_entry->IsLoopHeader()); |
| 3671 loop_entry->loop_information()->set_stack_check(stack_check); | 3667 loop_entry->loop_information()->set_stack_check(stack_check); |
| 3672 CHECK_BAILOUT(Visit(stmt->body())); | 3668 CHECK_BAILOUT(Visit(stmt->body())); |
| 3673 } | 3669 } |
| 3674 | 3670 |
| 3675 | 3671 |
| 3676 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 3672 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 3677 ASSERT(!HasStackOverflow()); | 3673 ASSERT(!HasStackOverflow()); |
| 3678 ASSERT(current_block() != NULL); | 3674 ASSERT(current_block() != NULL); |
| 3679 ASSERT(current_block()->HasPredecessor()); | 3675 ASSERT(current_block()->HasPredecessor()); |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3960 ASSERT(!HasStackOverflow()); | 3956 ASSERT(!HasStackOverflow()); |
| 3961 ASSERT(current_block() != NULL); | 3957 ASSERT(current_block() != NULL); |
| 3962 ASSERT(current_block()->HasPredecessor()); | 3958 ASSERT(current_block()->HasPredecessor()); |
| 3963 Handle<SharedFunctionInfo> shared_info = | 3959 Handle<SharedFunctionInfo> shared_info = |
| 3964 SearchSharedFunctionInfo(current_info()->shared_info()->code(), expr); | 3960 SearchSharedFunctionInfo(current_info()->shared_info()->code(), expr); |
| 3965 if (shared_info.is_null()) { | 3961 if (shared_info.is_null()) { |
| 3966 shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script()); | 3962 shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script()); |
| 3967 } | 3963 } |
| 3968 // We also have a stack overflow if the recursive compilation did. | 3964 // We also have a stack overflow if the recursive compilation did. |
| 3969 if (HasStackOverflow()) return; | 3965 if (HasStackOverflow()) return; |
| 3970 HValue* context = environment()->context(); | |
| 3971 HFunctionLiteral* instr = | 3966 HFunctionLiteral* instr = |
| 3972 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); | 3967 New<HFunctionLiteral>(shared_info, expr->pretenure()); |
|
danno
2013/09/25 11:44:28
nit: 4 indentation spaces
| |
| 3973 return ast_context()->ReturnInstruction(instr, expr->id()); | 3968 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 3974 } | 3969 } |
| 3975 | 3970 |
| 3976 | 3971 |
| 3977 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral( | 3972 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral( |
| 3978 SharedFunctionInfoLiteral* expr) { | 3973 SharedFunctionInfoLiteral* expr) { |
| 3979 ASSERT(!HasStackOverflow()); | 3974 ASSERT(!HasStackOverflow()); |
| 3980 ASSERT(current_block() != NULL); | 3975 ASSERT(current_block() != NULL); |
| 3981 ASSERT(current_block()->HasPredecessor()); | 3976 ASSERT(current_block()->HasPredecessor()); |
| 3982 return Bailout(kSharedFunctionInfoLiteral); | 3977 return Bailout(kSharedFunctionInfoLiteral); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4141 return ast_context()->ReturnInstruction(instr, expr->id()); | 4136 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 4142 } | 4137 } |
| 4143 | 4138 |
| 4144 | 4139 |
| 4145 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 4140 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 4146 ASSERT(!HasStackOverflow()); | 4141 ASSERT(!HasStackOverflow()); |
| 4147 ASSERT(current_block() != NULL); | 4142 ASSERT(current_block() != NULL); |
| 4148 ASSERT(current_block()->HasPredecessor()); | 4143 ASSERT(current_block()->HasPredecessor()); |
| 4149 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); | 4144 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); |
| 4150 Handle<FixedArray> literals(closure->literals()); | 4145 Handle<FixedArray> literals(closure->literals()); |
| 4151 HValue* context = environment()->context(); | 4146 HRegExpLiteral* instr = New<HRegExpLiteral>(literals, |
| 4152 | 4147 expr->pattern(), |
| 4153 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, | 4148 expr->flags(), |
| 4154 literals, | 4149 expr->literal_index()); |
| 4155 expr->pattern(), | |
| 4156 expr->flags(), | |
| 4157 expr->literal_index()); | |
| 4158 return ast_context()->ReturnInstruction(instr, expr->id()); | 4150 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 4159 } | 4151 } |
| 4160 | 4152 |
| 4161 | 4153 |
| 4162 static bool CanInlinePropertyAccess(Map* type) { | 4154 static bool CanInlinePropertyAccess(Map* type) { |
| 4163 return type->IsJSObjectMap() && | 4155 return type->IsJSObjectMap() && |
| 4164 !type->is_dictionary_map() && | 4156 !type->is_dictionary_map() && |
| 4165 !type->has_named_interceptor(); | 4157 !type->has_named_interceptor(); |
| 4166 } | 4158 } |
| 4167 | 4159 |
| (...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4841 } | 4833 } |
| 4842 | 4834 |
| 4843 if (info->lookup()->IsPropertyCallbacks()) { | 4835 if (info->lookup()->IsPropertyCallbacks()) { |
| 4844 Push(checked_object); | 4836 Push(checked_object); |
| 4845 if (FLAG_inline_accessors && | 4837 if (FLAG_inline_accessors && |
| 4846 can_inline_accessor && | 4838 can_inline_accessor && |
| 4847 TryInlineGetter(info->accessor(), ast_id, return_id)) { | 4839 TryInlineGetter(info->accessor(), ast_id, return_id)) { |
| 4848 return NULL; | 4840 return NULL; |
| 4849 } | 4841 } |
| 4850 Add<HPushArgument>(Pop()); | 4842 Add<HPushArgument>(Pop()); |
| 4851 return new(zone()) HCallConstantFunction(info->accessor(), 1); | 4843 return New<HCallConstantFunction>(info->accessor(), 1); |
| 4852 } | 4844 } |
| 4853 | 4845 |
| 4854 ASSERT(info->lookup()->IsConstant()); | 4846 ASSERT(info->lookup()->IsConstant()); |
| 4855 return New<HConstant>(info->constant()); | 4847 return New<HConstant>(info->constant()); |
| 4856 } | 4848 } |
| 4857 | 4849 |
| 4858 | 4850 |
| 4859 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( | 4851 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
| 4860 int position, | 4852 int position, |
| 4861 BailoutId ast_id, | 4853 BailoutId ast_id, |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5137 Handle<JSObject> holder; | 5129 Handle<JSObject> holder; |
| 5138 if (LookupSetter(map, name, &setter, &holder)) { | 5130 if (LookupSetter(map, name, &setter, &holder)) { |
| 5139 AddCheckConstantFunction(holder, object, map); | 5131 AddCheckConstantFunction(holder, object, map); |
| 5140 if (FLAG_inline_accessors && | 5132 if (FLAG_inline_accessors && |
| 5141 TryInlineSetter(setter, ast_id, return_id, value)) { | 5133 TryInlineSetter(setter, ast_id, return_id, value)) { |
| 5142 return; | 5134 return; |
| 5143 } | 5135 } |
| 5144 Drop(2); | 5136 Drop(2); |
| 5145 Add<HPushArgument>(object); | 5137 Add<HPushArgument>(object); |
| 5146 Add<HPushArgument>(value); | 5138 Add<HPushArgument>(value); |
| 5147 instr = new(zone()) HCallConstantFunction(setter, 2); | 5139 instr = New<HCallConstantFunction>(setter, 2); |
| 5148 } else { | 5140 } else { |
| 5149 Drop(2); | 5141 Drop(2); |
| 5150 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, | 5142 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, |
| 5151 name, | 5143 name, |
| 5152 value, | 5144 value, |
| 5153 map)); | 5145 map)); |
| 5154 } | 5146 } |
| 5155 } else if (types != NULL && types->length() > 1) { | 5147 } else if (types != NULL && types->length() > 1) { |
| 5156 Drop(2); | 5148 Drop(2); |
| 5157 return HandlePolymorphicStoreNamedField( | 5149 return HandlePolymorphicStoreNamedField( |
| (...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6127 Handle<JSFunction> caller = current_info()->closure(); | 6119 Handle<JSFunction> caller = current_info()->closure(); |
| 6128 SmartArrayPointer<char> caller_name = | 6120 SmartArrayPointer<char> caller_name = |
| 6129 caller->shared()->DebugName()->ToCString(); | 6121 caller->shared()->DebugName()->ToCString(); |
| 6130 PrintF("Trying to inline the polymorphic call to %s from %s\n", | 6122 PrintF("Trying to inline the polymorphic call to %s from %s\n", |
| 6131 *name->ToCString(), *caller_name); | 6123 *name->ToCString(), *caller_name); |
| 6132 } | 6124 } |
| 6133 | 6125 |
| 6134 if (!TryInlineCall(expr)) { | 6126 if (!TryInlineCall(expr)) { |
| 6135 int argument_count = expr->arguments()->length() + 1; // Includes receiver. | 6127 int argument_count = expr->arguments()->length() + 1; // Includes receiver. |
| 6136 HCallConstantFunction* call = | 6128 HCallConstantFunction* call = |
| 6137 new(zone()) HCallConstantFunction(expr->target(), argument_count); | 6129 New<HCallConstantFunction>(expr->target(), argument_count); |
| 6138 call->set_position(expr->position()); | 6130 call->set_position(expr->position()); |
| 6139 PreProcessCall(call); | 6131 PreProcessCall(call); |
| 6140 AddInstruction(call); | 6132 AddInstruction(call); |
| 6141 if (!ast_context()->IsEffect()) Push(call); | 6133 if (!ast_context()->IsEffect()) Push(call); |
| 6142 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 6134 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 6143 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 6135 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
| 6144 } | 6136 } |
| 6145 | 6137 |
| 6146 return true; | 6138 return true; |
| 6147 } | 6139 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6244 PrintF("Trying to inline the polymorphic call to %s from %s\n", | 6236 PrintF("Trying to inline the polymorphic call to %s from %s\n", |
| 6245 *name->ToCString(), | 6237 *name->ToCString(), |
| 6246 *caller_name); | 6238 *caller_name); |
| 6247 } | 6239 } |
| 6248 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { | 6240 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { |
| 6249 // Trying to inline will signal that we should bailout from the | 6241 // Trying to inline will signal that we should bailout from the |
| 6250 // entire compilation by setting stack overflow on the visitor. | 6242 // entire compilation by setting stack overflow on the visitor. |
| 6251 if (HasStackOverflow()) return; | 6243 if (HasStackOverflow()) return; |
| 6252 } else { | 6244 } else { |
| 6253 HCallConstantFunction* call = | 6245 HCallConstantFunction* call = |
| 6254 new(zone()) HCallConstantFunction(expr->target(), argument_count); | 6246 New<HCallConstantFunction>(expr->target(), argument_count); |
| 6255 call->set_position(expr->position()); | 6247 call->set_position(expr->position()); |
| 6256 PreProcessCall(call); | 6248 PreProcessCall(call); |
| 6257 AddInstruction(call); | 6249 AddInstruction(call); |
| 6258 if (!ast_context()->IsEffect()) Push(call); | 6250 if (!ast_context()->IsEffect()) Push(call); |
| 6259 } | 6251 } |
| 6260 | 6252 |
| 6261 if (current_block() != NULL) current_block()->Goto(join); | 6253 if (current_block() != NULL) current_block()->Goto(join); |
| 6262 set_current_block(if_false); | 6254 set_current_block(if_false); |
| 6263 } | 6255 } |
| 6264 | 6256 |
| 6265 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 6257 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
| 6266 // know about and do not want to handle ones we've never seen. Otherwise | 6258 // know about and do not want to handle ones we've never seen. Otherwise |
| 6267 // use a generic IC. | 6259 // use a generic IC. |
| 6268 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { | 6260 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { |
| 6269 // Because the deopt may be the only path in the polymorphic call, make sure | 6261 // Because the deopt may be the only path in the polymorphic call, make sure |
| 6270 // that the environment stack matches the depth on deopt that it otherwise | 6262 // that the environment stack matches the depth on deopt that it otherwise |
| 6271 // would have had after a successful call. | 6263 // would have had after a successful call. |
| 6272 Drop(argument_count); | 6264 Drop(argument_count); |
| 6273 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); | 6265 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); |
| 6274 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); | 6266 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); |
| 6275 } else { | 6267 } else { |
| 6276 HValue* context = environment()->context(); | 6268 HCallNamed* call = New<HCallNamed>(name, argument_count); |
| 6277 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); | |
| 6278 call->set_position(expr->position()); | 6269 call->set_position(expr->position()); |
| 6279 PreProcessCall(call); | 6270 PreProcessCall(call); |
| 6280 | 6271 |
| 6281 if (join != NULL) { | 6272 if (join != NULL) { |
| 6282 AddInstruction(call); | 6273 AddInstruction(call); |
| 6283 if (!ast_context()->IsEffect()) Push(call); | 6274 if (!ast_context()->IsEffect()) Push(call); |
| 6284 current_block()->Goto(join); | 6275 current_block()->Goto(join); |
| 6285 } else { | 6276 } else { |
| 6286 return ast_context()->ReturnInstruction(call, expr->id()); | 6277 return ast_context()->ReturnInstruction(call, expr->id()); |
| 6287 } | 6278 } |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7026 | 7017 |
| 7027 CHECK_ALIVE(VisitForValue(prop->key())); | 7018 CHECK_ALIVE(VisitForValue(prop->key())); |
| 7028 // Push receiver and key like the non-optimized code generator expects it. | 7019 // Push receiver and key like the non-optimized code generator expects it. |
| 7029 HValue* key = Pop(); | 7020 HValue* key = Pop(); |
| 7030 HValue* receiver = Pop(); | 7021 HValue* receiver = Pop(); |
| 7031 Push(key); | 7022 Push(key); |
| 7032 Push(receiver); | 7023 Push(receiver); |
| 7033 | 7024 |
| 7034 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7025 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 7035 | 7026 |
| 7036 HValue* context = environment()->context(); | 7027 call = New<HCallKeyed>(key, argument_count); |
| 7037 call = new(zone()) HCallKeyed(context, key, argument_count); | |
| 7038 call->set_position(expr->position()); | 7028 call->set_position(expr->position()); |
| 7039 Drop(argument_count + 1); // 1 is the key. | 7029 Drop(argument_count + 1); // 1 is the key. |
| 7040 return ast_context()->ReturnInstruction(call, expr->id()); | 7030 return ast_context()->ReturnInstruction(call, expr->id()); |
| 7041 } | 7031 } |
| 7042 | 7032 |
| 7043 // Named function call. | 7033 // Named function call. |
| 7044 if (TryCallApply(expr)) return; | 7034 if (TryCallApply(expr)) return; |
| 7045 | 7035 |
| 7046 CHECK_ALIVE(VisitForValue(prop->obj())); | 7036 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 7047 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 7037 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 7066 PrintF("\n"); | 7056 PrintF("\n"); |
| 7067 } | 7057 } |
| 7068 return; | 7058 return; |
| 7069 } | 7059 } |
| 7070 | 7060 |
| 7071 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || | 7061 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || |
| 7072 expr->check_type() != RECEIVER_MAP_CHECK) { | 7062 expr->check_type() != RECEIVER_MAP_CHECK) { |
| 7073 // When the target has a custom call IC generator, use the IC, | 7063 // When the target has a custom call IC generator, use the IC, |
| 7074 // because it is likely to generate better code. Also use the IC | 7064 // because it is likely to generate better code. Also use the IC |
| 7075 // when a primitive receiver check is required. | 7065 // when a primitive receiver check is required. |
| 7076 HValue* context = environment()->context(); | 7066 call = PreProcessCall(New<HCallNamed>(name, argument_count)); |
| 7077 call = PreProcessCall( | |
| 7078 new(zone()) HCallNamed(context, name, argument_count)); | |
| 7079 } else { | 7067 } else { |
| 7080 AddCheckConstantFunction(expr->holder(), receiver, map); | 7068 AddCheckConstantFunction(expr->holder(), receiver, map); |
| 7081 | 7069 |
| 7082 if (TryInlineCall(expr)) return; | 7070 if (TryInlineCall(expr)) return; |
| 7083 call = PreProcessCall( | 7071 call = PreProcessCall( |
| 7084 new(zone()) HCallConstantFunction(expr->target(), | 7072 New<HCallConstantFunction>(expr->target(), argument_count)); |
| 7085 argument_count)); | |
| 7086 } | 7073 } |
| 7087 } else if (types != NULL && types->length() > 1) { | 7074 } else if (types != NULL && types->length() > 1) { |
| 7088 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); | 7075 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); |
| 7089 HandlePolymorphicCallNamed(expr, receiver, types, name); | 7076 HandlePolymorphicCallNamed(expr, receiver, types, name); |
| 7090 return; | 7077 return; |
| 7091 | 7078 |
| 7092 } else { | 7079 } else { |
| 7093 HValue* context = environment()->context(); | 7080 call = PreProcessCall(New<HCallNamed>(name, argument_count)); |
| 7094 call = PreProcessCall( | |
| 7095 new(zone()) HCallNamed(context, name, argument_count)); | |
| 7096 } | 7081 } |
| 7097 | 7082 |
| 7098 } else { | 7083 } else { |
| 7099 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 7084 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 7100 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 7085 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
| 7101 return Bailout(kPossibleDirectCallToEval); | 7086 return Bailout(kPossibleDirectCallToEval); |
| 7102 } | 7087 } |
| 7103 | 7088 |
| 7104 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); | 7089 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); |
| 7105 if (global_call) { | 7090 if (global_call) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7145 } | 7130 } |
| 7146 if (TryInlineCall(expr)) return; | 7131 if (TryInlineCall(expr)) return; |
| 7147 | 7132 |
| 7148 if (expr->target().is_identical_to(current_info()->closure())) { | 7133 if (expr->target().is_identical_to(current_info()->closure())) { |
| 7149 graph()->MarkRecursive(); | 7134 graph()->MarkRecursive(); |
| 7150 } | 7135 } |
| 7151 | 7136 |
| 7152 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { | 7137 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { |
| 7153 // When the target has a custom call IC generator, use the IC, | 7138 // When the target has a custom call IC generator, use the IC, |
| 7154 // because it is likely to generate better code. | 7139 // because it is likely to generate better code. |
| 7155 HValue* context = environment()->context(); | 7140 call = PreProcessCall(New<HCallNamed>(var->name(), argument_count)); |
| 7156 call = PreProcessCall( | |
| 7157 new(zone()) HCallNamed(context, var->name(), argument_count)); | |
| 7158 } else { | 7141 } else { |
| 7159 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), | 7142 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), |
| 7160 argument_count)); | 7143 argument_count)); |
| 7161 } | 7144 } |
| 7162 } else { | 7145 } else { |
| 7163 HGlobalObject* receiver = Add<HGlobalObject>(); | 7146 HGlobalObject* receiver = Add<HGlobalObject>(); |
| 7164 PushAndAdd(New<HPushArgument>(receiver)); | 7147 PushAndAdd(New<HPushArgument>(receiver)); |
| 7165 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7148 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 7166 | 7149 |
| 7167 call = New<HCallGlobal>(var->name(), argument_count); | 7150 call = New<HCallGlobal>(var->name(), argument_count); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7221 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize && | 7204 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize && |
| 7222 constructor->initial_map()->InitialPropertiesLength() == 0; | 7205 constructor->initial_map()->InitialPropertiesLength() == 0; |
| 7223 } | 7206 } |
| 7224 | 7207 |
| 7225 | 7208 |
| 7226 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { | 7209 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { |
| 7227 ASSERT(!HasStackOverflow()); | 7210 ASSERT(!HasStackOverflow()); |
| 7228 ASSERT(current_block() != NULL); | 7211 ASSERT(current_block() != NULL); |
| 7229 ASSERT(current_block()->HasPredecessor()); | 7212 ASSERT(current_block()->HasPredecessor()); |
| 7230 int argument_count = expr->arguments()->length() + 1; // Plus constructor. | 7213 int argument_count = expr->arguments()->length() + 1; // Plus constructor. |
| 7231 HValue* context = environment()->context(); | |
| 7232 Factory* factory = isolate()->factory(); | 7214 Factory* factory = isolate()->factory(); |
| 7233 | 7215 |
| 7234 if (FLAG_inline_construct && | 7216 if (FLAG_inline_construct && |
| 7235 expr->IsMonomorphic() && | 7217 expr->IsMonomorphic() && |
| 7236 IsAllocationInlineable(expr->target())) { | 7218 IsAllocationInlineable(expr->target())) { |
| 7237 // The constructor function is on the stack in the unoptimized code | 7219 // The constructor function is on the stack in the unoptimized code |
| 7238 // during evaluation of the arguments. | 7220 // during evaluation of the arguments. |
| 7239 CHECK_ALIVE(VisitForValue(expr->expression())); | 7221 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 7240 HValue* function = Top(); | 7222 HValue* function = Top(); |
| 7241 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 7223 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7310 HInstruction* instr = current_block()->last(); | 7292 HInstruction* instr = current_block()->last(); |
| 7311 while (instr != initial_map_value) { | 7293 while (instr != initial_map_value) { |
| 7312 HInstruction* prev_instr = instr->previous(); | 7294 HInstruction* prev_instr = instr->previous(); |
| 7313 instr->DeleteAndReplaceWith(NULL); | 7295 instr->DeleteAndReplaceWith(NULL); |
| 7314 instr = prev_instr; | 7296 instr = prev_instr; |
| 7315 } | 7297 } |
| 7316 initial_map_value->DeleteAndReplaceWith(NULL); | 7298 initial_map_value->DeleteAndReplaceWith(NULL); |
| 7317 receiver->DeleteAndReplaceWith(NULL); | 7299 receiver->DeleteAndReplaceWith(NULL); |
| 7318 check->DeleteAndReplaceWith(NULL); | 7300 check->DeleteAndReplaceWith(NULL); |
| 7319 environment()->SetExpressionStackAt(receiver_index, function); | 7301 environment()->SetExpressionStackAt(receiver_index, function); |
| 7320 HInstruction* call = PreProcessCall( | 7302 HInstruction* call = |
| 7321 new(zone()) HCallNew(context, function, argument_count)); | 7303 PreProcessCall(New<HCallNew>(function, argument_count)); |
| 7322 call->set_position(expr->position()); | 7304 call->set_position(expr->position()); |
| 7323 return ast_context()->ReturnInstruction(call, expr->id()); | 7305 return ast_context()->ReturnInstruction(call, expr->id()); |
| 7324 } else { | 7306 } else { |
| 7325 // The constructor function is both an operand to the instruction and an | 7307 // The constructor function is both an operand to the instruction and an |
| 7326 // argument to the construct call. | 7308 // argument to the construct call. |
| 7327 Handle<JSFunction> array_function( | 7309 Handle<JSFunction> array_function( |
| 7328 isolate()->global_context()->array_function(), isolate()); | 7310 isolate()->global_context()->array_function(), isolate()); |
| 7329 CHECK_ALIVE(VisitArgument(expr->expression())); | 7311 CHECK_ALIVE(VisitArgument(expr->expression())); |
| 7330 HValue* constructor = HPushArgument::cast(Top())->argument(); | 7312 HValue* constructor = HPushArgument::cast(Top())->argument(); |
| 7331 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7313 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 7332 HBinaryCall* call; | 7314 HBinaryCall* call; |
| 7333 if (expr->target().is_identical_to(array_function)) { | 7315 if (expr->target().is_identical_to(array_function)) { |
| 7334 Handle<Cell> cell = expr->allocation_info_cell(); | 7316 Handle<Cell> cell = expr->allocation_info_cell(); |
| 7335 Add<HCheckValue>(constructor, array_function); | 7317 Add<HCheckValue>(constructor, array_function); |
| 7336 call = new(zone()) HCallNewArray(context, constructor, argument_count, | 7318 call = New<HCallNewArray>(constructor, argument_count, |
| 7337 cell, expr->elements_kind()); | 7319 cell, expr->elements_kind()); |
| 7338 } else { | 7320 } else { |
| 7339 call = new(zone()) HCallNew(context, constructor, argument_count); | 7321 call = New<HCallNew>(constructor, argument_count); |
| 7340 } | 7322 } |
| 7341 Drop(argument_count); | 7323 Drop(argument_count); |
| 7342 call->set_position(expr->position()); | 7324 call->set_position(expr->position()); |
| 7343 return ast_context()->ReturnInstruction(call, expr->id()); | 7325 return ast_context()->ReturnInstruction(call, expr->id()); |
| 7344 } | 7326 } |
| 7345 } | 7327 } |
| 7346 | 7328 |
| 7347 | 7329 |
| 7348 // Support for generating inlined runtime functions. | 7330 // Support for generating inlined runtime functions. |
| 7349 | 7331 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7454 | 7436 |
| 7455 void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { | 7437 void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { |
| 7456 CHECK_ALIVE(VisitForEffect(expr->expression())); | 7438 CHECK_ALIVE(VisitForEffect(expr->expression())); |
| 7457 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 7439 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
| 7458 } | 7440 } |
| 7459 | 7441 |
| 7460 | 7442 |
| 7461 void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { | 7443 void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
| 7462 CHECK_ALIVE(VisitForTypeOf(expr->expression())); | 7444 CHECK_ALIVE(VisitForTypeOf(expr->expression())); |
| 7463 HValue* value = Pop(); | 7445 HValue* value = Pop(); |
| 7464 HValue* context = environment()->context(); | 7446 HInstruction* instr = New<HTypeof>(value); |
| 7465 HInstruction* instr = new(zone()) HTypeof(context, value); | |
| 7466 return ast_context()->ReturnInstruction(instr, expr->id()); | 7447 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 7467 } | 7448 } |
| 7468 | 7449 |
| 7469 | 7450 |
| 7470 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { | 7451 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { |
| 7471 if (ast_context()->IsTest()) { | 7452 if (ast_context()->IsTest()) { |
| 7472 TestContext* context = TestContext::cast(ast_context()); | 7453 TestContext* context = TestContext::cast(ast_context()); |
| 7473 VisitForControl(expr->expression(), | 7454 VisitForControl(expr->expression(), |
| 7474 context->if_false(), | 7455 context->if_false(), |
| 7475 context->if_true()); | 7456 context->if_true()); |
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8244 | 8225 |
| 8245 // If the target is not null we have found a known global function that is | 8226 // If the target is not null we have found a known global function that is |
| 8246 // assumed to stay the same for this instanceof. | 8227 // assumed to stay the same for this instanceof. |
| 8247 if (target.is_null()) { | 8228 if (target.is_null()) { |
| 8248 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); | 8229 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); |
| 8249 result->set_position(expr->position()); | 8230 result->set_position(expr->position()); |
| 8250 return ast_context()->ReturnInstruction(result, expr->id()); | 8231 return ast_context()->ReturnInstruction(result, expr->id()); |
| 8251 } else { | 8232 } else { |
| 8252 Add<HCheckValue>(right, target); | 8233 Add<HCheckValue>(right, target); |
| 8253 HInstanceOfKnownGlobal* result = | 8234 HInstanceOfKnownGlobal* result = |
| 8254 new(zone()) HInstanceOfKnownGlobal(context, left, target); | 8235 New<HInstanceOfKnownGlobal>(left, target); |
| 8255 result->set_position(expr->position()); | 8236 result->set_position(expr->position()); |
| 8256 return ast_context()->ReturnInstruction(result, expr->id()); | 8237 return ast_context()->ReturnInstruction(result, expr->id()); |
| 8257 } | 8238 } |
| 8258 | 8239 |
| 8259 // Code below assumes that we don't fall through. | 8240 // Code below assumes that we don't fall through. |
| 8260 UNREACHABLE(); | 8241 UNREACHABLE(); |
| 8261 } else if (op == Token::IN) { | 8242 } else if (op == Token::IN) { |
| 8262 HValue* function = AddLoadJSBuiltin(Builtins::IN); | 8243 HValue* function = AddLoadJSBuiltin(Builtins::IN); |
| 8263 Add<HPushArgument>(left); | 8244 Add<HPushArgument>(left); |
| 8264 Add<HPushArgument>(right); | 8245 Add<HPushArgument>(right); |
| 8265 // TODO(olivf) InvokeFunction produces a check for the parameter count, | 8246 // TODO(olivf) InvokeFunction produces a check for the parameter count, |
| 8266 // even though we are certain to pass the correct number of arguments here. | 8247 // even though we are certain to pass the correct number of arguments here. |
| 8267 HInstruction* result = new(zone()) HInvokeFunction(context, function, 2); | 8248 HInstruction* result = New<HInvokeFunction>(function, 2); |
| 8268 result->set_position(expr->position()); | 8249 result->set_position(expr->position()); |
| 8269 return ast_context()->ReturnInstruction(result, expr->id()); | 8250 return ast_context()->ReturnInstruction(result, expr->id()); |
| 8270 } | 8251 } |
| 8271 | 8252 |
| 8272 // Cases handled below depend on collected type feedback. They should | 8253 // Cases handled below depend on collected type feedback. They should |
| 8273 // soft deoptimize when there is no type feedback. | 8254 // soft deoptimize when there is no type feedback. |
| 8274 if (combined_type->Is(Type::None())) { | 8255 if (combined_type->Is(Type::None())) { |
| 8275 Add<HDeoptimize>("Insufficient type feedback for combined type " | 8256 Add<HDeoptimize>("Insufficient type feedback for combined type " |
| 8276 "of binary operation", | 8257 "of binary operation", |
| 8277 Deoptimizer::SOFT); | 8258 Deoptimizer::SOFT); |
| (...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9056 } | 9037 } |
| 9057 | 9038 |
| 9058 | 9039 |
| 9059 // Fast support for StringAdd. | 9040 // Fast support for StringAdd. |
| 9060 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { | 9041 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
| 9061 ASSERT_EQ(2, call->arguments()->length()); | 9042 ASSERT_EQ(2, call->arguments()->length()); |
| 9062 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9043 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 9063 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9044 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 9064 HValue* right = Pop(); | 9045 HValue* right = Pop(); |
| 9065 HValue* left = Pop(); | 9046 HValue* left = Pop(); |
| 9066 HValue* context = environment()->context(); | 9047 HInstruction* result = New<HStringAdd>(left, right, STRING_ADD_CHECK_BOTH); |
| 9067 HInstruction* result = HStringAdd::New( | |
| 9068 zone(), context, left, right, STRING_ADD_CHECK_BOTH); | |
| 9069 return ast_context()->ReturnInstruction(result, call->id()); | 9048 return ast_context()->ReturnInstruction(result, call->id()); |
| 9070 } | 9049 } |
| 9071 | 9050 |
| 9072 | 9051 |
| 9073 // Fast support for SubString. | 9052 // Fast support for SubString. |
| 9074 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { | 9053 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { |
| 9075 ASSERT_EQ(3, call->arguments()->length()); | 9054 ASSERT_EQ(3, call->arguments()->length()); |
| 9076 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9055 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
| 9077 HValue* context = environment()->context(); | 9056 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); |
| 9078 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); | |
| 9079 Drop(3); | 9057 Drop(3); |
| 9080 return ast_context()->ReturnInstruction(result, call->id()); | 9058 return ast_context()->ReturnInstruction(result, call->id()); |
| 9081 } | 9059 } |
| 9082 | 9060 |
| 9083 | 9061 |
| 9084 // Fast support for StringCompare. | 9062 // Fast support for StringCompare. |
| 9085 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { | 9063 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { |
| 9086 ASSERT_EQ(2, call->arguments()->length()); | 9064 ASSERT_EQ(2, call->arguments()->length()); |
| 9087 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9065 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
| 9088 HValue* context = environment()->context(); | 9066 HCallStub* result = New<HCallStub>(CodeStub::StringCompare, 2); |
| 9089 HCallStub* result = | |
| 9090 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); | |
| 9091 Drop(2); | 9067 Drop(2); |
| 9092 return ast_context()->ReturnInstruction(result, call->id()); | 9068 return ast_context()->ReturnInstruction(result, call->id()); |
| 9093 } | 9069 } |
| 9094 | 9070 |
| 9095 | 9071 |
| 9096 // Support for direct calls from JavaScript to native RegExp code. | 9072 // Support for direct calls from JavaScript to native RegExp code. |
| 9097 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { | 9073 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { |
| 9098 ASSERT_EQ(4, call->arguments()->length()); | 9074 ASSERT_EQ(4, call->arguments()->length()); |
| 9099 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9075 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
| 9100 HValue* context = environment()->context(); | 9076 HCallStub* result = New<HCallStub>(CodeStub::RegExpExec, 4); |
| 9101 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); | |
| 9102 Drop(4); | 9077 Drop(4); |
| 9103 return ast_context()->ReturnInstruction(result, call->id()); | 9078 return ast_context()->ReturnInstruction(result, call->id()); |
| 9104 } | 9079 } |
| 9105 | 9080 |
| 9106 | 9081 |
| 9107 // Construct a RegExp exec result with two in-object properties. | 9082 // Construct a RegExp exec result with two in-object properties. |
| 9108 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { | 9083 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { |
| 9109 ASSERT_EQ(3, call->arguments()->length()); | 9084 ASSERT_EQ(3, call->arguments()->length()); |
| 9110 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9085 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
| 9111 HValue* context = environment()->context(); | 9086 HCallStub* result = New<HCallStub>(CodeStub::RegExpConstructResult, 3); |
| 9112 HCallStub* result = | |
| 9113 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); | |
| 9114 Drop(3); | 9087 Drop(3); |
| 9115 return ast_context()->ReturnInstruction(result, call->id()); | 9088 return ast_context()->ReturnInstruction(result, call->id()); |
| 9116 } | 9089 } |
| 9117 | 9090 |
| 9118 | 9091 |
| 9119 // Support for fast native caches. | 9092 // Support for fast native caches. |
| 9120 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { | 9093 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { |
| 9121 return Bailout(kInlinedRuntimeFunctionGetFromCache); | 9094 return Bailout(kInlinedRuntimeFunctionGetFromCache); |
| 9122 } | 9095 } |
| 9123 | 9096 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9181 HValue* right = Pop(); | 9154 HValue* right = Pop(); |
| 9182 HValue* left = Pop(); | 9155 HValue* left = Pop(); |
| 9183 HInstruction* result = HPower::New(zone(), context(), left, right); | 9156 HInstruction* result = HPower::New(zone(), context(), left, right); |
| 9184 return ast_context()->ReturnInstruction(result, call->id()); | 9157 return ast_context()->ReturnInstruction(result, call->id()); |
| 9185 } | 9158 } |
| 9186 | 9159 |
| 9187 | 9160 |
| 9188 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { | 9161 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { |
| 9189 ASSERT_EQ(1, call->arguments()->length()); | 9162 ASSERT_EQ(1, call->arguments()->length()); |
| 9190 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9163 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
| 9191 HValue* context = environment()->context(); | 9164 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1); |
| 9192 HCallStub* result = | |
| 9193 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | |
| 9194 result->set_transcendental_type(TranscendentalCache::SIN); | 9165 result->set_transcendental_type(TranscendentalCache::SIN); |
| 9195 Drop(1); | 9166 Drop(1); |
| 9196 return ast_context()->ReturnInstruction(result, call->id()); | 9167 return ast_context()->ReturnInstruction(result, call->id()); |
| 9197 } | 9168 } |
| 9198 | 9169 |
| 9199 | 9170 |
| 9200 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) { | 9171 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) { |
| 9201 ASSERT_EQ(1, call->arguments()->length()); | 9172 ASSERT_EQ(1, call->arguments()->length()); |
| 9202 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9173 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
| 9203 HValue* context = environment()->context(); | 9174 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1); |
| 9204 HCallStub* result = | |
| 9205 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | |
| 9206 result->set_transcendental_type(TranscendentalCache::COS); | 9175 result->set_transcendental_type(TranscendentalCache::COS); |
| 9207 Drop(1); | 9176 Drop(1); |
| 9208 return ast_context()->ReturnInstruction(result, call->id()); | 9177 return ast_context()->ReturnInstruction(result, call->id()); |
| 9209 } | 9178 } |
| 9210 | 9179 |
| 9211 | 9180 |
| 9212 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) { | 9181 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) { |
| 9213 ASSERT_EQ(1, call->arguments()->length()); | 9182 ASSERT_EQ(1, call->arguments()->length()); |
| 9214 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9183 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
| 9215 HValue* context = environment()->context(); | 9184 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1); |
| 9216 HCallStub* result = | |
| 9217 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | |
| 9218 result->set_transcendental_type(TranscendentalCache::TAN); | 9185 result->set_transcendental_type(TranscendentalCache::TAN); |
| 9219 Drop(1); | 9186 Drop(1); |
| 9220 return ast_context()->ReturnInstruction(result, call->id()); | 9187 return ast_context()->ReturnInstruction(result, call->id()); |
| 9221 } | 9188 } |
| 9222 | 9189 |
| 9223 | 9190 |
| 9224 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) { | 9191 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) { |
| 9225 ASSERT_EQ(1, call->arguments()->length()); | 9192 ASSERT_EQ(1, call->arguments()->length()); |
| 9226 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9193 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
| 9227 HValue* context = environment()->context(); | 9194 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1); |
| 9228 HCallStub* result = | |
| 9229 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | |
| 9230 result->set_transcendental_type(TranscendentalCache::LOG); | 9195 result->set_transcendental_type(TranscendentalCache::LOG); |
| 9231 Drop(1); | 9196 Drop(1); |
| 9232 return ast_context()->ReturnInstruction(result, call->id()); | 9197 return ast_context()->ReturnInstruction(result, call->id()); |
| 9233 } | 9198 } |
| 9234 | 9199 |
| 9235 | 9200 |
| 9236 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { | 9201 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { |
| 9237 ASSERT(call->arguments()->length() == 1); | 9202 ASSERT(call->arguments()->length() == 1); |
| 9238 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9203 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 9239 HValue* value = Pop(); | 9204 HValue* value = Pop(); |
| 9240 HValue* context = environment()->context(); | 9205 HInstruction* result = New<HUnaryMathOperation>(value, kMathSqrt); |
| 9241 HInstruction* result = | |
| 9242 HUnaryMathOperation::New(zone(), context, value, kMathSqrt); | |
| 9243 return ast_context()->ReturnInstruction(result, call->id()); | 9206 return ast_context()->ReturnInstruction(result, call->id()); |
| 9244 } | 9207 } |
| 9245 | 9208 |
| 9246 | 9209 |
| 9247 // Check whether two RegExps are equivalent | 9210 // Check whether two RegExps are equivalent |
| 9248 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { | 9211 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { |
| 9249 return Bailout(kInlinedRuntimeFunctionIsRegExpEquivalent); | 9212 return Bailout(kInlinedRuntimeFunctionIsRegExpEquivalent); |
| 9250 } | 9213 } |
| 9251 | 9214 |
| 9252 | 9215 |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9888 if (ShouldProduceTraceOutput()) { | 9851 if (ShouldProduceTraceOutput()) { |
| 9889 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9852 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 9890 } | 9853 } |
| 9891 | 9854 |
| 9892 #ifdef DEBUG | 9855 #ifdef DEBUG |
| 9893 graph_->Verify(false); // No full verify. | 9856 graph_->Verify(false); // No full verify. |
| 9894 #endif | 9857 #endif |
| 9895 } | 9858 } |
| 9896 | 9859 |
| 9897 } } // namespace v8::internal | 9860 } } // namespace v8::internal |
| OLD | NEW |