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 |