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

Side by Side Diff: src/hydrogen.cc

Issue 153953005: A64: Synchronize with r16993. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-check-elimination.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 18 matching lines...) Expand all
29 29
30 #include <algorithm> 30 #include <algorithm>
31 31
32 #include "v8.h" 32 #include "v8.h"
33 #include "codegen.h" 33 #include "codegen.h"
34 #include "full-codegen.h" 34 #include "full-codegen.h"
35 #include "hashmap.h" 35 #include "hashmap.h"
36 #include "hydrogen-bce.h" 36 #include "hydrogen-bce.h"
37 #include "hydrogen-bch.h" 37 #include "hydrogen-bch.h"
38 #include "hydrogen-canonicalize.h" 38 #include "hydrogen-canonicalize.h"
39 #include "hydrogen-check-elimination.h"
39 #include "hydrogen-dce.h" 40 #include "hydrogen-dce.h"
40 #include "hydrogen-dehoist.h" 41 #include "hydrogen-dehoist.h"
41 #include "hydrogen-deoptimizing-mark.h" 42 #include "hydrogen-deoptimizing-mark.h"
42 #include "hydrogen-environment-liveness.h" 43 #include "hydrogen-environment-liveness.h"
43 #include "hydrogen-escape-analysis.h" 44 #include "hydrogen-escape-analysis.h"
44 #include "hydrogen-infer-representation.h" 45 #include "hydrogen-infer-representation.h"
45 #include "hydrogen-infer-types.h" 46 #include "hydrogen-infer-types.h"
46 #include "hydrogen-load-elimination.h" 47 #include "hydrogen-load-elimination.h"
47 #include "hydrogen-gvn.h" 48 #include "hydrogen-gvn.h"
48 #include "hydrogen-mark-deoptimize.h" 49 #include "hydrogen-mark-deoptimize.h"
(...skipping 2191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2240 loop_entry->PostProcessLoopHeader(statement); 2241 loop_entry->PostProcessLoopHeader(statement);
2241 if (break_block != NULL) { 2242 if (break_block != NULL) {
2242 if (loop_successor != NULL) loop_successor->Goto(break_block); 2243 if (loop_successor != NULL) loop_successor->Goto(break_block);
2243 break_block->SetJoinId(statement->ExitId()); 2244 break_block->SetJoinId(statement->ExitId());
2244 return break_block; 2245 return break_block;
2245 } 2246 }
2246 return loop_successor; 2247 return loop_successor;
2247 } 2248 }
2248 2249
2249 2250
2251 // Build a new loop header block and set it as the current block.
2252 HBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry() {
2253 HBasicBlock* loop_entry = CreateLoopHeaderBlock();
2254 current_block()->Goto(loop_entry);
2255 set_current_block(loop_entry);
2256 return loop_entry;
2257 }
2258
2259
2260 HBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry(
2261 IterationStatement* statement) {
2262 HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement)
2263 ? osr()->BuildOsrLoopEntry(statement)
2264 : BuildLoopEntry();
2265 return loop_entry;
2266 }
2267
2268
2250 void HBasicBlock::FinishExit(HControlInstruction* instruction) { 2269 void HBasicBlock::FinishExit(HControlInstruction* instruction) {
2251 Finish(instruction); 2270 Finish(instruction);
2252 ClearEnvironment(); 2271 ClearEnvironment();
2253 } 2272 }
2254 2273
2255 2274
2256 HGraph::HGraph(CompilationInfo* info) 2275 HGraph::HGraph(CompilationInfo* info)
2257 : isolate_(info->isolate()), 2276 : isolate_(info->isolate()),
2258 next_block_id_(0), 2277 next_block_id_(0),
2259 entry_block_(NULL), 2278 entry_block_(NULL),
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
3056 set_current_block(body_entry); 3075 set_current_block(body_entry);
3057 3076
3058 // Handle implicit declaration of the function name in named function 3077 // Handle implicit declaration of the function name in named function
3059 // expressions before other declarations. 3078 // expressions before other declarations.
3060 if (scope->is_function_scope() && scope->function() != NULL) { 3079 if (scope->is_function_scope() && scope->function() != NULL) {
3061 VisitVariableDeclaration(scope->function()); 3080 VisitVariableDeclaration(scope->function());
3062 } 3081 }
3063 VisitDeclarations(scope->declarations()); 3082 VisitDeclarations(scope->declarations());
3064 Add<HSimulate>(BailoutId::Declarations()); 3083 Add<HSimulate>(BailoutId::Declarations());
3065 3084
3066 HValue* context = environment()->context(); 3085 Add<HStackCheck>(HStackCheck::kFunctionEntry);
3067 Add<HStackCheck>(context, HStackCheck::kFunctionEntry);
3068 3086
3069 VisitStatements(current_info()->function()->body()); 3087 VisitStatements(current_info()->function()->body());
3070 if (HasStackOverflow()) return false; 3088 if (HasStackOverflow()) return false;
3071 3089
3072 if (current_block() != NULL) { 3090 if (current_block() != NULL) {
3073 Add<HReturn>(graph()->GetConstantUndefined()); 3091 Add<HReturn>(graph()->GetConstantUndefined());
3074 set_current_block(NULL); 3092 set_current_block(NULL);
3075 } 3093 }
3076 3094
3077 // If the checksum of the number of type info changes is the same as the 3095 // If the checksum of the number of type info changes is the same as the
3078 // last time this function was compiled, then this recompile is likely not 3096 // last time this function was compiled, then this recompile is likely not
3079 // due to missing/inadequate type feedback, but rather too aggressive 3097 // due to missing/inadequate type feedback, but rather too aggressive
3080 // optimization. Disable optimistic LICM in that case. 3098 // optimization. Disable optimistic LICM in that case.
3081 Handle<Code> unoptimized_code(current_info()->shared_info()->code()); 3099 Handle<Code> unoptimized_code(current_info()->shared_info()->code());
3082 ASSERT(unoptimized_code->kind() == Code::FUNCTION); 3100 ASSERT(unoptimized_code->kind() == Code::FUNCTION);
3083 Handle<TypeFeedbackInfo> type_info( 3101 Handle<TypeFeedbackInfo> type_info(
3084 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); 3102 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info()));
3085 int checksum = type_info->own_type_change_checksum(); 3103 int checksum = type_info->own_type_change_checksum();
3086 int composite_checksum = graph()->update_type_change_checksum(checksum); 3104 int composite_checksum = graph()->update_type_change_checksum(checksum);
3087 graph()->set_use_optimistic_licm( 3105 graph()->set_use_optimistic_licm(
3088 !type_info->matches_inlined_type_change_checksum(composite_checksum)); 3106 !type_info->matches_inlined_type_change_checksum(composite_checksum));
3089 type_info->set_inlined_type_change_checksum(composite_checksum); 3107 type_info->set_inlined_type_change_checksum(composite_checksum);
3090 3108
3091 // Perform any necessary OSR-specific cleanups or changes to the graph. 3109 // Perform any necessary OSR-specific cleanups or changes to the graph.
3092 osr_->FinishGraph(); 3110 osr()->FinishGraph();
3093 3111
3094 return true; 3112 return true;
3095 } 3113 }
3096 3114
3097 3115
3098 bool HGraph::Optimize(BailoutReason* bailout_reason) { 3116 bool HGraph::Optimize(BailoutReason* bailout_reason) {
3099 OrderBlocks(); 3117 OrderBlocks();
3100 AssignDominators(); 3118 AssignDominators();
3101 3119
3102 // We need to create a HConstant "zero" now so that GVN will fold every 3120 // We need to create a HConstant "zero" now so that GVN will fold every
(...skipping 15 matching lines...) Expand all
3118 if (!CheckConstPhiUses()) { 3136 if (!CheckConstPhiUses()) {
3119 *bailout_reason = kUnsupportedPhiUseOfConstVariable; 3137 *bailout_reason = kUnsupportedPhiUseOfConstVariable;
3120 return false; 3138 return false;
3121 } 3139 }
3122 Run<HRedundantPhiEliminationPhase>(); 3140 Run<HRedundantPhiEliminationPhase>();
3123 if (!CheckArgumentsPhiUses()) { 3141 if (!CheckArgumentsPhiUses()) {
3124 *bailout_reason = kUnsupportedPhiUseOfArguments; 3142 *bailout_reason = kUnsupportedPhiUseOfArguments;
3125 return false; 3143 return false;
3126 } 3144 }
3127 3145
3128 // Remove dead code and phis 3146 if (FLAG_check_elimination) Run<HCheckEliminationPhase>();
3129 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 3147 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
3130
3131 if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>(); 3148 if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>();
3132 3149
3133 if (FLAG_load_elimination) Run<HLoadEliminationPhase>(); 3150 if (FLAG_load_elimination) Run<HLoadEliminationPhase>();
3134 3151
3135 CollectPhis(); 3152 CollectPhis();
3136 3153
3137 if (has_osr()) osr()->FinishOsrValues(); 3154 if (has_osr()) osr()->FinishOsrValues();
3138 3155
3139 Run<HInferRepresentationPhase>(); 3156 Run<HInferRepresentationPhase>();
3140 3157
(...skipping 17 matching lines...) Expand all
3158 if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>(); 3175 if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>();
3159 3176
3160 if (FLAG_use_range) Run<HRangeAnalysisPhase>(); 3177 if (FLAG_use_range) Run<HRangeAnalysisPhase>();
3161 3178
3162 Run<HComputeChangeUndefinedToNaN>(); 3179 Run<HComputeChangeUndefinedToNaN>();
3163 Run<HComputeMinusZeroChecksPhase>(); 3180 Run<HComputeMinusZeroChecksPhase>();
3164 3181
3165 // Eliminate redundant stack checks on backwards branches. 3182 // Eliminate redundant stack checks on backwards branches.
3166 Run<HStackCheckEliminationPhase>(); 3183 Run<HStackCheckEliminationPhase>();
3167 3184
3168 if (FLAG_array_bounds_checks_elimination) { 3185 if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>();
3169 Run<HBoundsCheckEliminationPhase>(); 3186 if (FLAG_array_bounds_checks_hoisting) Run<HBoundsCheckHoistingPhase>();
3170 }
3171 if (FLAG_array_bounds_checks_hoisting) {
3172 Run<HBoundsCheckHoistingPhase>();
3173 }
3174 if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>(); 3187 if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>();
3175 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 3188 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
3176 3189
3177 RestoreActualValues(); 3190 RestoreActualValues();
3178 3191
3179 return true; 3192 return true;
3180 } 3193 }
3181 3194
3182 3195
3183 void HGraph::RestoreActualValues() { 3196 void HGraph::RestoreActualValues() {
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
3513 int clause_count = clauses->length(); 3526 int clause_count = clauses->length();
3514 if (clause_count > kCaseClauseLimit) { 3527 if (clause_count > kCaseClauseLimit) {
3515 return Bailout(kSwitchStatementTooManyClauses); 3528 return Bailout(kSwitchStatementTooManyClauses);
3516 } 3529 }
3517 3530
3518 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); 3531 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH);
3519 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { 3532 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) {
3520 return Bailout(kSwitchStatementMixedOrNonLiteralSwitchLabels); 3533 return Bailout(kSwitchStatementMixedOrNonLiteralSwitchLabels);
3521 } 3534 }
3522 3535
3523 HValue* context = environment()->context();
3524
3525 CHECK_ALIVE(VisitForValue(stmt->tag())); 3536 CHECK_ALIVE(VisitForValue(stmt->tag()));
3526 Add<HSimulate>(stmt->EntryId()); 3537 Add<HSimulate>(stmt->EntryId());
3527 HValue* tag_value = Pop(); 3538 HValue* tag_value = Pop();
3528 HBasicBlock* first_test_block = current_block(); 3539 HBasicBlock* first_test_block = current_block();
3529 3540
3530 HUnaryControlInstruction* string_check = NULL; 3541 HUnaryControlInstruction* string_check = NULL;
3531 HBasicBlock* not_string_block = NULL; 3542 HBasicBlock* not_string_block = NULL;
3532 3543
3533 // Test switch's tag value if all clauses are string literals 3544 // Test switch's tag value if all clauses are string literals
3534 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) { 3545 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) {
(...skipping 30 matching lines...) Expand all
3565 } 3576 }
3566 3577
3567 HCompareNumericAndBranch* compare_ = 3578 HCompareNumericAndBranch* compare_ =
3568 New<HCompareNumericAndBranch>(tag_value, 3579 New<HCompareNumericAndBranch>(tag_value,
3569 label_value, 3580 label_value,
3570 Token::EQ_STRICT); 3581 Token::EQ_STRICT);
3571 compare_->set_observed_input_representation( 3582 compare_->set_observed_input_representation(
3572 Representation::Smi(), Representation::Smi()); 3583 Representation::Smi(), Representation::Smi());
3573 compare = compare_; 3584 compare = compare_;
3574 } else { 3585 } else {
3575 compare = new(zone()) HStringCompareAndBranch(context, tag_value, 3586 compare = New<HStringCompareAndBranch>(tag_value,
3576 label_value, 3587 label_value,
3577 Token::EQ_STRICT); 3588 Token::EQ_STRICT);
3578 } 3589 }
3579 3590
3580 compare->SetSuccessorAt(0, body_block); 3591 compare->SetSuccessorAt(0, body_block);
3581 compare->SetSuccessorAt(1, next_test_block); 3592 compare->SetSuccessorAt(1, next_test_block);
3582 current_block()->Finish(compare); 3593 current_block()->Finish(compare);
3583 3594
3584 set_current_block(next_test_block); 3595 set_current_block(next_test_block);
3585 } 3596 }
3586 3597
3587 // Save the current block to use for the default or to join with the 3598 // 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
3659 set_current_block(break_block); 3670 set_current_block(break_block);
3660 } 3671 }
3661 } 3672 }
3662 3673
3663 3674
3664 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, 3675 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
3665 HBasicBlock* loop_entry, 3676 HBasicBlock* loop_entry,
3666 BreakAndContinueInfo* break_info) { 3677 BreakAndContinueInfo* break_info) {
3667 BreakAndContinueScope push(break_info, this); 3678 BreakAndContinueScope push(break_info, this);
3668 Add<HSimulate>(stmt->StackCheckId()); 3679 Add<HSimulate>(stmt->StackCheckId());
3669 HValue* context = environment()->context(); 3680 HStackCheck* stack_check =
3670 HStackCheck* stack_check = HStackCheck::cast(Add<HStackCheck>( 3681 HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch));
3671 context, HStackCheck::kBackwardsBranch));
3672 ASSERT(loop_entry->IsLoopHeader()); 3682 ASSERT(loop_entry->IsLoopHeader());
3673 loop_entry->loop_information()->set_stack_check(stack_check); 3683 loop_entry->loop_information()->set_stack_check(stack_check);
3674 CHECK_BAILOUT(Visit(stmt->body())); 3684 CHECK_BAILOUT(Visit(stmt->body()));
3675 } 3685 }
3676 3686
3677 3687
3678 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 3688 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
3679 ASSERT(!HasStackOverflow()); 3689 ASSERT(!HasStackOverflow());
3680 ASSERT(current_block() != NULL); 3690 ASSERT(current_block() != NULL);
3681 ASSERT(current_block()->HasPredecessor()); 3691 ASSERT(current_block()->HasPredecessor());
3682 ASSERT(current_block() != NULL); 3692 ASSERT(current_block() != NULL);
3683 HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt); 3693 HBasicBlock* loop_entry = BuildLoopEntry(stmt);
3684 3694
3685 BreakAndContinueInfo break_info(stmt); 3695 BreakAndContinueInfo break_info(stmt);
3686 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); 3696 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
3687 HBasicBlock* body_exit = 3697 HBasicBlock* body_exit =
3688 JoinContinue(stmt, current_block(), break_info.continue_block()); 3698 JoinContinue(stmt, current_block(), break_info.continue_block());
3689 HBasicBlock* loop_successor = NULL; 3699 HBasicBlock* loop_successor = NULL;
3690 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { 3700 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) {
3691 set_current_block(body_exit); 3701 set_current_block(body_exit);
3692 // The block for a true condition, the actual predecessor block of the 3702 // The block for a true condition, the actual predecessor block of the
3693 // back edge. 3703 // back edge.
(...skipping 18 matching lines...) Expand all
3712 break_info.break_block()); 3722 break_info.break_block());
3713 set_current_block(loop_exit); 3723 set_current_block(loop_exit);
3714 } 3724 }
3715 3725
3716 3726
3717 void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 3727 void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
3718 ASSERT(!HasStackOverflow()); 3728 ASSERT(!HasStackOverflow());
3719 ASSERT(current_block() != NULL); 3729 ASSERT(current_block() != NULL);
3720 ASSERT(current_block()->HasPredecessor()); 3730 ASSERT(current_block()->HasPredecessor());
3721 ASSERT(current_block() != NULL); 3731 ASSERT(current_block() != NULL);
3722 HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt); 3732 HBasicBlock* loop_entry = BuildLoopEntry(stmt);
3723 3733
3724 // If the condition is constant true, do not generate a branch. 3734 // If the condition is constant true, do not generate a branch.
3725 HBasicBlock* loop_successor = NULL; 3735 HBasicBlock* loop_successor = NULL;
3726 if (!stmt->cond()->ToBooleanIsTrue()) { 3736 if (!stmt->cond()->ToBooleanIsTrue()) {
3727 HBasicBlock* body_entry = graph()->CreateBasicBlock(); 3737 HBasicBlock* body_entry = graph()->CreateBasicBlock();
3728 loop_successor = graph()->CreateBasicBlock(); 3738 loop_successor = graph()->CreateBasicBlock();
3729 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); 3739 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor));
3730 if (body_entry->HasPredecessor()) { 3740 if (body_entry->HasPredecessor()) {
3731 body_entry->SetJoinId(stmt->BodyId()); 3741 body_entry->SetJoinId(stmt->BodyId());
3732 set_current_block(body_entry); 3742 set_current_block(body_entry);
(...skipping 21 matching lines...) Expand all
3754 3764
3755 3765
3756 void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { 3766 void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) {
3757 ASSERT(!HasStackOverflow()); 3767 ASSERT(!HasStackOverflow());
3758 ASSERT(current_block() != NULL); 3768 ASSERT(current_block() != NULL);
3759 ASSERT(current_block()->HasPredecessor()); 3769 ASSERT(current_block()->HasPredecessor());
3760 if (stmt->init() != NULL) { 3770 if (stmt->init() != NULL) {
3761 CHECK_ALIVE(Visit(stmt->init())); 3771 CHECK_ALIVE(Visit(stmt->init()));
3762 } 3772 }
3763 ASSERT(current_block() != NULL); 3773 ASSERT(current_block() != NULL);
3764 HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt); 3774 HBasicBlock* loop_entry = BuildLoopEntry(stmt);
3765 3775
3766 HBasicBlock* loop_successor = NULL; 3776 HBasicBlock* loop_successor = NULL;
3767 if (stmt->cond() != NULL) { 3777 if (stmt->cond() != NULL) {
3768 HBasicBlock* body_entry = graph()->CreateBasicBlock(); 3778 HBasicBlock* body_entry = graph()->CreateBasicBlock();
3769 loop_successor = graph()->CreateBasicBlock(); 3779 loop_successor = graph()->CreateBasicBlock();
3770 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); 3780 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor));
3771 if (body_entry->HasPredecessor()) { 3781 if (body_entry->HasPredecessor()) {
3772 body_entry->SetJoinId(stmt->BodyId()); 3782 body_entry->SetJoinId(stmt->BodyId());
3773 set_current_block(body_entry); 3783 set_current_block(body_entry);
3774 } 3784 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
3837 Push(map); 3847 Push(map);
3838 Push(array); 3848 Push(array);
3839 Push(enum_length); 3849 Push(enum_length);
3840 Push(start_index); 3850 Push(start_index);
3841 3851
3842 HInstruction* index_cache = Add<HForInCacheArray>( 3852 HInstruction* index_cache = Add<HForInCacheArray>(
3843 enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex); 3853 enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex);
3844 HForInCacheArray::cast(array)->set_index_cache( 3854 HForInCacheArray::cast(array)->set_index_cache(
3845 HForInCacheArray::cast(index_cache)); 3855 HForInCacheArray::cast(index_cache));
3846 3856
3847 HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt); 3857 HBasicBlock* loop_entry = BuildLoopEntry(stmt);
3848 3858
3849 HValue* index = environment()->ExpressionStackAt(0); 3859 HValue* index = environment()->ExpressionStackAt(0);
3850 HValue* limit = environment()->ExpressionStackAt(1); 3860 HValue* limit = environment()->ExpressionStackAt(1);
3851 3861
3852 // Check that we still have more keys. 3862 // Check that we still have more keys.
3853 HCompareNumericAndBranch* compare_index = 3863 HCompareNumericAndBranch* compare_index =
3854 New<HCompareNumericAndBranch>(index, limit, Token::LT); 3864 New<HCompareNumericAndBranch>(index, limit, Token::LT);
3855 compare_index->set_observed_input_representation( 3865 compare_index->set_observed_input_representation(
3856 Representation::Smi(), Representation::Smi()); 3866 Representation::Smi(), Representation::Smi());
3857 3867
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3962 ASSERT(!HasStackOverflow()); 3972 ASSERT(!HasStackOverflow());
3963 ASSERT(current_block() != NULL); 3973 ASSERT(current_block() != NULL);
3964 ASSERT(current_block()->HasPredecessor()); 3974 ASSERT(current_block()->HasPredecessor());
3965 Handle<SharedFunctionInfo> shared_info = 3975 Handle<SharedFunctionInfo> shared_info =
3966 SearchSharedFunctionInfo(current_info()->shared_info()->code(), expr); 3976 SearchSharedFunctionInfo(current_info()->shared_info()->code(), expr);
3967 if (shared_info.is_null()) { 3977 if (shared_info.is_null()) {
3968 shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script()); 3978 shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script());
3969 } 3979 }
3970 // We also have a stack overflow if the recursive compilation did. 3980 // We also have a stack overflow if the recursive compilation did.
3971 if (HasStackOverflow()) return; 3981 if (HasStackOverflow()) return;
3972 HValue* context = environment()->context();
3973 HFunctionLiteral* instr = 3982 HFunctionLiteral* instr =
3974 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); 3983 New<HFunctionLiteral>(shared_info, expr->pretenure());
3975 return ast_context()->ReturnInstruction(instr, expr->id()); 3984 return ast_context()->ReturnInstruction(instr, expr->id());
3976 } 3985 }
3977 3986
3978 3987
3979 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral( 3988 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral(
3980 SharedFunctionInfoLiteral* expr) { 3989 SharedFunctionInfoLiteral* expr) {
3981 ASSERT(!HasStackOverflow()); 3990 ASSERT(!HasStackOverflow());
3982 ASSERT(current_block() != NULL); 3991 ASSERT(current_block() != NULL);
3983 ASSERT(current_block()->HasPredecessor()); 3992 ASSERT(current_block()->HasPredecessor());
3984 return Bailout(kSharedFunctionInfoLiteral); 3993 return Bailout(kSharedFunctionInfoLiteral);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
4143 return ast_context()->ReturnInstruction(instr, expr->id()); 4152 return ast_context()->ReturnInstruction(instr, expr->id());
4144 } 4153 }
4145 4154
4146 4155
4147 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 4156 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
4148 ASSERT(!HasStackOverflow()); 4157 ASSERT(!HasStackOverflow());
4149 ASSERT(current_block() != NULL); 4158 ASSERT(current_block() != NULL);
4150 ASSERT(current_block()->HasPredecessor()); 4159 ASSERT(current_block()->HasPredecessor());
4151 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4160 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
4152 Handle<FixedArray> literals(closure->literals()); 4161 Handle<FixedArray> literals(closure->literals());
4153 HValue* context = environment()->context(); 4162 HRegExpLiteral* instr = New<HRegExpLiteral>(literals,
4154 4163 expr->pattern(),
4155 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, 4164 expr->flags(),
4156 literals, 4165 expr->literal_index());
4157 expr->pattern(),
4158 expr->flags(),
4159 expr->literal_index());
4160 return ast_context()->ReturnInstruction(instr, expr->id()); 4166 return ast_context()->ReturnInstruction(instr, expr->id());
4161 } 4167 }
4162 4168
4163 4169
4164 static bool CanInlinePropertyAccess(Map* type) { 4170 static bool CanInlinePropertyAccess(Map* type) {
4165 return type->IsJSObjectMap() && 4171 return type->IsJSObjectMap() &&
4166 !type->is_dictionary_map() && 4172 !type->is_dictionary_map() &&
4167 !type->has_named_interceptor(); 4173 !type->has_named_interceptor();
4168 } 4174 }
4169 4175
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
4761 map->LookupDescriptor(*holder_, *name_, &lookup_); 4767 map->LookupDescriptor(*holder_, *name_, &lookup_);
4762 if (lookup_.IsFound()) return LoadResult(map); 4768 if (lookup_.IsFound()) return LoadResult(map);
4763 } 4769 }
4764 lookup_.NotFound(); 4770 lookup_.NotFound();
4765 return true; 4771 return true;
4766 } 4772 }
4767 4773
4768 4774
4769 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadMonomorphic() { 4775 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadMonomorphic() {
4770 if (!CanInlinePropertyAccess(*map_)) return IsStringLength(); 4776 if (!CanInlinePropertyAccess(*map_)) return IsStringLength();
4771 if (IsArrayLength()) return true; 4777 if (IsJSObjectFieldAccessor()) return true;
4772 if (!LookupDescriptor()) return false; 4778 if (!LookupDescriptor()) return false;
4773 if (lookup_.IsFound()) return true; 4779 if (lookup_.IsFound()) return true;
4774 return LookupInPrototypes(); 4780 return LookupInPrototypes();
4775 } 4781 }
4776 4782
4777 4783
4778 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic( 4784 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic(
4779 SmallMapList* types) { 4785 SmallMapList* types) {
4780 ASSERT(map_.is_identical_to(types->first())); 4786 ASSERT(map_.is_identical_to(types->first()));
4781 if (!CanLoadMonomorphic()) return false; 4787 if (!CanLoadMonomorphic()) return false;
(...skipping 11 matching lines...) Expand all
4793 for (int i = 1; i < types->length(); ++i) { 4799 for (int i = 1; i < types->length(); ++i) {
4794 Handle<Map> test_map = types->at(i); 4800 Handle<Map> test_map = types->at(i);
4795 if (test_map->instance_type() != JS_ARRAY_TYPE) return false; 4801 if (test_map->instance_type() != JS_ARRAY_TYPE) return false;
4796 if (IsFastElementsKind(test_map->elements_kind()) != is_fast) { 4802 if (IsFastElementsKind(test_map->elements_kind()) != is_fast) {
4797 return false; 4803 return false;
4798 } 4804 }
4799 } 4805 }
4800 return true; 4806 return true;
4801 } 4807 }
4802 4808
4803 if (IsTypedArrayLength()) { 4809 if (IsJSObjectFieldAccessor()) {
4810 InstanceType instance_type = map_->instance_type();
4804 for (int i = 1; i < types->length(); ++i) { 4811 for (int i = 1; i < types->length(); ++i) {
4805 if (types->at(i)->instance_type() != JS_TYPED_ARRAY_TYPE) return false; 4812 if (types->at(i)->instance_type() != instance_type) return false;
4806 } 4813 }
4807 return true; 4814 return true;
4808 } 4815 }
4809 4816
4810 for (int i = 1; i < types->length(); ++i) { 4817 for (int i = 1; i < types->length(); ++i) {
4811 PropertyAccessInfo test_info(isolate(), types->at(i), name_); 4818 PropertyAccessInfo test_info(isolate(), types->at(i), name_);
4812 if (!test_info.IsCompatibleForLoad(this)) return false; 4819 if (!test_info.IsCompatibleForLoad(this)) return false;
4813 } 4820 }
4814 4821
4815 return true; 4822 return true;
4816 } 4823 }
4817 4824
4818 4825
4819 HInstruction* HOptimizedGraphBuilder::BuildLoadMonomorphic( 4826 HInstruction* HOptimizedGraphBuilder::BuildLoadMonomorphic(
4820 PropertyAccessInfo* info, 4827 PropertyAccessInfo* info,
4821 HValue* object, 4828 HValue* object,
4822 HInstruction* checked_object, 4829 HInstruction* checked_object,
4823 BailoutId ast_id, 4830 BailoutId ast_id,
4824 BailoutId return_id, 4831 BailoutId return_id,
4825 bool can_inline_accessor) { 4832 bool can_inline_accessor) {
4826 if (info->IsStringLength()) {
4827 return New<HLoadNamedField>(
4828 checked_object, HObjectAccess::ForStringLength());
4829 }
4830 4833
4831 if (info->IsArrayLength()) { 4834 HObjectAccess access = HObjectAccess::ForMap(); // bogus default
4832 return New<HLoadNamedField>( 4835 if (info->GetJSObjectFieldAccess(&access)) {
4833 checked_object, HObjectAccess::ForArrayLength( 4836 return New<HLoadNamedField>(checked_object, access);
4834 info->map()->elements_kind()));
4835 }
4836
4837 if (info->IsTypedArrayLength()) {
4838 return New<HLoadNamedField>(
4839 checked_object, HObjectAccess::ForTypedArrayLength());
4840 } 4837 }
4841 4838
4842 HValue* checked_holder = checked_object; 4839 HValue* checked_holder = checked_object;
4843 if (info->has_holder()) { 4840 if (info->has_holder()) {
4844 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); 4841 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype()));
4845 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); 4842 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder());
4846 } 4843 }
4847 4844
4848 if (!info->lookup()->IsFound()) return graph()->GetConstantUndefined(); 4845 if (!info->lookup()->IsFound()) return graph()->GetConstantUndefined();
4849 4846
4850 if (info->lookup()->IsField()) { 4847 if (info->lookup()->IsField()) {
4851 return BuildLoadNamedField(checked_holder, info->access()); 4848 return BuildLoadNamedField(checked_holder, info->access());
4852 } 4849 }
4853 4850
4854 if (info->lookup()->IsPropertyCallbacks()) { 4851 if (info->lookup()->IsPropertyCallbacks()) {
4855 Push(checked_object); 4852 Push(checked_object);
4856 if (FLAG_inline_accessors && 4853 if (FLAG_inline_accessors &&
4857 can_inline_accessor && 4854 can_inline_accessor &&
4858 TryInlineGetter(info->accessor(), ast_id, return_id)) { 4855 TryInlineGetter(info->accessor(), ast_id, return_id)) {
4859 return NULL; 4856 return NULL;
4860 } 4857 }
4861 Add<HPushArgument>(Pop()); 4858 Add<HPushArgument>(Pop());
4862 return new(zone()) HCallConstantFunction(info->accessor(), 1); 4859 return New<HCallConstantFunction>(info->accessor(), 1);
4863 } 4860 }
4864 4861
4865 ASSERT(info->lookup()->IsConstant()); 4862 ASSERT(info->lookup()->IsConstant());
4866 return New<HConstant>(info->constant()); 4863 return New<HConstant>(info->constant());
4867 } 4864 }
4868 4865
4869 4866
4870 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 4867 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
4871 int position, 4868 int position,
4872 BailoutId ast_id, 4869 BailoutId ast_id,
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
5148 Handle<JSObject> holder; 5145 Handle<JSObject> holder;
5149 if (LookupSetter(map, name, &setter, &holder)) { 5146 if (LookupSetter(map, name, &setter, &holder)) {
5150 AddCheckConstantFunction(holder, object, map); 5147 AddCheckConstantFunction(holder, object, map);
5151 if (FLAG_inline_accessors && 5148 if (FLAG_inline_accessors &&
5152 TryInlineSetter(setter, ast_id, return_id, value)) { 5149 TryInlineSetter(setter, ast_id, return_id, value)) {
5153 return; 5150 return;
5154 } 5151 }
5155 Drop(2); 5152 Drop(2);
5156 Add<HPushArgument>(object); 5153 Add<HPushArgument>(object);
5157 Add<HPushArgument>(value); 5154 Add<HPushArgument>(value);
5158 instr = new(zone()) HCallConstantFunction(setter, 2); 5155 instr = New<HCallConstantFunction>(setter, 2);
5159 } else { 5156 } else {
5160 Drop(2); 5157 Drop(2);
5161 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, 5158 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
5162 name, 5159 name,
5163 value, 5160 value,
5164 map)); 5161 map));
5165 } 5162 }
5166 } else if (types != NULL && types->length() > 1) { 5163 } else if (types != NULL && types->length() > 1) {
5167 Drop(2); 5164 Drop(2);
5168 return HandlePolymorphicStoreNamedField( 5165 return HandlePolymorphicStoreNamedField(
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
5489 // We don't optimize functions with invalid left-hand sides in 5486 // We don't optimize functions with invalid left-hand sides in
5490 // assignments, count operations, or for-in. Consequently throw can 5487 // assignments, count operations, or for-in. Consequently throw can
5491 // currently only occur in an effect context. 5488 // currently only occur in an effect context.
5492 ASSERT(ast_context()->IsEffect()); 5489 ASSERT(ast_context()->IsEffect());
5493 CHECK_ALIVE(VisitForValue(expr->exception())); 5490 CHECK_ALIVE(VisitForValue(expr->exception()));
5494 5491
5495 HValue* value = environment()->Pop(); 5492 HValue* value = environment()->Pop();
5496 HThrow* instr = Add<HThrow>(value); 5493 HThrow* instr = Add<HThrow>(value);
5497 instr->set_position(expr->position()); 5494 instr->set_position(expr->position());
5498 Add<HSimulate>(expr->id()); 5495 Add<HSimulate>(expr->id());
5496
5497 // If the throw definitely exits the function, we can finish with a dummy
5498 // control flow at this point. This is not the case if the throw is inside
5499 // an inlined function which may be replaced.
5500 if (call_context() == NULL) {
5501 current_block()->FinishExit(new(zone()) HAbnormalExit);
5502 set_current_block(NULL);
5503 }
5499 } 5504 }
5500 5505
5501 5506
5502 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, 5507 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
5503 HObjectAccess access) { 5508 HObjectAccess access) {
5504 if (FLAG_track_double_fields && access.representation().IsDouble()) { 5509 if (FLAG_track_double_fields && access.representation().IsDouble()) {
5505 // load the heap number 5510 // load the heap number
5506 HLoadNamedField* heap_number = Add<HLoadNamedField>( 5511 HLoadNamedField* heap_number = Add<HLoadNamedField>(
5507 object, access.WithRepresentation(Representation::Tagged())); 5512 object, access.WithRepresentation(Representation::Tagged()));
5508 heap_number->set_type(HType::HeapNumber()); 5513 heap_number->set_type(HType::HeapNumber());
(...skipping 23 matching lines...) Expand all
5532 Property* expr) { 5537 Property* expr) {
5533 if (expr->IsUninitialized()) { 5538 if (expr->IsUninitialized()) {
5534 Add<HDeoptimize>("Insufficient type feedback for generic named load", 5539 Add<HDeoptimize>("Insufficient type feedback for generic named load",
5535 Deoptimizer::SOFT); 5540 Deoptimizer::SOFT);
5536 } 5541 }
5537 HValue* context = environment()->context(); 5542 HValue* context = environment()->context();
5538 return new(zone()) HLoadNamedGeneric(context, object, name); 5543 return new(zone()) HLoadNamedGeneric(context, object, name);
5539 } 5544 }
5540 5545
5541 5546
5542 HInstruction* HOptimizedGraphBuilder::BuildCallGetter(
5543 HValue* object,
5544 Handle<Map> map,
5545 Handle<JSFunction> getter,
5546 Handle<JSObject> holder) {
5547 AddCheckConstantFunction(holder, object, map);
5548 Add<HPushArgument>(object);
5549 return new(zone()) HCallConstantFunction(getter, 1);
5550 }
5551
5552 5547
5553 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, 5548 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object,
5554 HValue* key) { 5549 HValue* key) {
5555 HValue* context = environment()->context(); 5550 HValue* context = environment()->context();
5556 return new(zone()) HLoadKeyedGeneric(context, object, key); 5551 return new(zone()) HLoadKeyedGeneric(context, object, key);
5557 } 5552 }
5558 5553
5559 5554
5560 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { 5555 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) {
5561 // Loads from a "stock" fast holey double arrays can elide the hole check. 5556 // Loads from a "stock" fast holey double arrays can elide the hole check.
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
6148 Handle<JSFunction> caller = current_info()->closure(); 6143 Handle<JSFunction> caller = current_info()->closure();
6149 SmartArrayPointer<char> caller_name = 6144 SmartArrayPointer<char> caller_name =
6150 caller->shared()->DebugName()->ToCString(); 6145 caller->shared()->DebugName()->ToCString();
6151 PrintF("Trying to inline the polymorphic call to %s from %s\n", 6146 PrintF("Trying to inline the polymorphic call to %s from %s\n",
6152 *name->ToCString(), *caller_name); 6147 *name->ToCString(), *caller_name);
6153 } 6148 }
6154 6149
6155 if (!TryInlineCall(expr)) { 6150 if (!TryInlineCall(expr)) {
6156 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 6151 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
6157 HCallConstantFunction* call = 6152 HCallConstantFunction* call =
6158 new(zone()) HCallConstantFunction(expr->target(), argument_count); 6153 New<HCallConstantFunction>(expr->target(), argument_count);
6159 call->set_position(expr->position()); 6154 call->set_position(expr->position());
6160 PreProcessCall(call); 6155 PreProcessCall(call);
6161 AddInstruction(call); 6156 AddInstruction(call);
6162 if (!ast_context()->IsEffect()) Push(call); 6157 if (!ast_context()->IsEffect()) Push(call);
6163 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 6158 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
6164 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6159 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6165 } 6160 }
6166 6161
6167 return true; 6162 return true;
6168 } 6163 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
6265 PrintF("Trying to inline the polymorphic call to %s from %s\n", 6260 PrintF("Trying to inline the polymorphic call to %s from %s\n",
6266 *name->ToCString(), 6261 *name->ToCString(),
6267 *caller_name); 6262 *caller_name);
6268 } 6263 }
6269 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { 6264 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) {
6270 // Trying to inline will signal that we should bailout from the 6265 // Trying to inline will signal that we should bailout from the
6271 // entire compilation by setting stack overflow on the visitor. 6266 // entire compilation by setting stack overflow on the visitor.
6272 if (HasStackOverflow()) return; 6267 if (HasStackOverflow()) return;
6273 } else { 6268 } else {
6274 HCallConstantFunction* call = 6269 HCallConstantFunction* call =
6275 new(zone()) HCallConstantFunction(expr->target(), argument_count); 6270 New<HCallConstantFunction>(expr->target(), argument_count);
6276 call->set_position(expr->position()); 6271 call->set_position(expr->position());
6277 PreProcessCall(call); 6272 PreProcessCall(call);
6278 AddInstruction(call); 6273 AddInstruction(call);
6279 if (!ast_context()->IsEffect()) Push(call); 6274 if (!ast_context()->IsEffect()) Push(call);
6280 } 6275 }
6281 6276
6282 if (current_block() != NULL) current_block()->Goto(join); 6277 if (current_block() != NULL) current_block()->Goto(join);
6283 set_current_block(if_false); 6278 set_current_block(if_false);
6284 } 6279 }
6285 6280
6286 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6281 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6287 // know about and do not want to handle ones we've never seen. Otherwise 6282 // know about and do not want to handle ones we've never seen. Otherwise
6288 // use a generic IC. 6283 // use a generic IC.
6289 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 6284 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
6290 // Because the deopt may be the only path in the polymorphic call, make sure 6285 // Because the deopt may be the only path in the polymorphic call, make sure
6291 // that the environment stack matches the depth on deopt that it otherwise 6286 // that the environment stack matches the depth on deopt that it otherwise
6292 // would have had after a successful call. 6287 // would have had after a successful call.
6293 Drop(argument_count); 6288 Drop(argument_count);
6294 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); 6289 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0());
6295 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); 6290 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join);
6296 } else { 6291 } else {
6297 HValue* context = environment()->context(); 6292 HCallNamed* call = New<HCallNamed>(name, argument_count);
6298 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);
6299 call->set_position(expr->position()); 6293 call->set_position(expr->position());
6300 PreProcessCall(call); 6294 PreProcessCall(call);
6301 6295
6302 if (join != NULL) { 6296 if (join != NULL) {
6303 AddInstruction(call); 6297 AddInstruction(call);
6304 if (!ast_context()->IsEffect()) Push(call); 6298 if (!ast_context()->IsEffect()) Push(call);
6305 current_block()->Goto(join); 6299 current_block()->Goto(join);
6306 } else { 6300 } else {
6307 return ast_context()->ReturnInstruction(call, expr->id()); 6301 return ast_context()->ReturnInstruction(call, expr->id());
6308 } 6302 }
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
7047 7041
7048 CHECK_ALIVE(VisitForValue(prop->key())); 7042 CHECK_ALIVE(VisitForValue(prop->key()));
7049 // Push receiver and key like the non-optimized code generator expects it. 7043 // Push receiver and key like the non-optimized code generator expects it.
7050 HValue* key = Pop(); 7044 HValue* key = Pop();
7051 HValue* receiver = Pop(); 7045 HValue* receiver = Pop();
7052 Push(key); 7046 Push(key);
7053 Push(receiver); 7047 Push(receiver);
7054 7048
7055 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7049 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7056 7050
7057 HValue* context = environment()->context(); 7051 call = New<HCallKeyed>(key, argument_count);
7058 call = new(zone()) HCallKeyed(context, key, argument_count);
7059 call->set_position(expr->position()); 7052 call->set_position(expr->position());
7060 Drop(argument_count + 1); // 1 is the key. 7053 Drop(argument_count + 1); // 1 is the key.
7061 return ast_context()->ReturnInstruction(call, expr->id()); 7054 return ast_context()->ReturnInstruction(call, expr->id());
7062 } 7055 }
7063 7056
7064 // Named function call. 7057 // Named function call.
7065 if (TryCallApply(expr)) return; 7058 if (TryCallApply(expr)) return;
7066 7059
7067 CHECK_ALIVE(VisitForValue(prop->obj())); 7060 CHECK_ALIVE(VisitForValue(prop->obj()));
7068 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7061 CHECK_ALIVE(VisitExpressions(expr->arguments()));
(...skipping 18 matching lines...) Expand all
7087 PrintF("\n"); 7080 PrintF("\n");
7088 } 7081 }
7089 return; 7082 return;
7090 } 7083 }
7091 7084
7092 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || 7085 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) ||
7093 expr->check_type() != RECEIVER_MAP_CHECK) { 7086 expr->check_type() != RECEIVER_MAP_CHECK) {
7094 // When the target has a custom call IC generator, use the IC, 7087 // When the target has a custom call IC generator, use the IC,
7095 // because it is likely to generate better code. Also use the IC 7088 // because it is likely to generate better code. Also use the IC
7096 // when a primitive receiver check is required. 7089 // when a primitive receiver check is required.
7097 HValue* context = environment()->context(); 7090 call = PreProcessCall(New<HCallNamed>(name, argument_count));
7098 call = PreProcessCall(
7099 new(zone()) HCallNamed(context, name, argument_count));
7100 } else { 7091 } else {
7101 AddCheckConstantFunction(expr->holder(), receiver, map); 7092 AddCheckConstantFunction(expr->holder(), receiver, map);
7102 7093
7103 if (TryInlineCall(expr)) return; 7094 if (TryInlineCall(expr)) return;
7104 call = PreProcessCall( 7095 call = PreProcessCall(
7105 new(zone()) HCallConstantFunction(expr->target(), 7096 New<HCallConstantFunction>(expr->target(), argument_count));
7106 argument_count));
7107 } 7097 }
7108 } else if (types != NULL && types->length() > 1) { 7098 } else if (types != NULL && types->length() > 1) {
7109 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); 7099 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK);
7110 HandlePolymorphicCallNamed(expr, receiver, types, name); 7100 HandlePolymorphicCallNamed(expr, receiver, types, name);
7111 return; 7101 return;
7112 7102
7113 } else { 7103 } else {
7114 HValue* context = environment()->context(); 7104 call = PreProcessCall(New<HCallNamed>(name, argument_count));
7115 call = PreProcessCall(
7116 new(zone()) HCallNamed(context, name, argument_count));
7117 } 7105 }
7118 7106
7119 } else { 7107 } else {
7120 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 7108 VariableProxy* proxy = expr->expression()->AsVariableProxy();
7121 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 7109 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
7122 return Bailout(kPossibleDirectCallToEval); 7110 return Bailout(kPossibleDirectCallToEval);
7123 } 7111 }
7124 7112
7125 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); 7113 bool global_call = proxy != NULL && proxy->var()->IsUnallocated();
7126 if (global_call) { 7114 if (global_call) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
7166 } 7154 }
7167 if (TryInlineCall(expr)) return; 7155 if (TryInlineCall(expr)) return;
7168 7156
7169 if (expr->target().is_identical_to(current_info()->closure())) { 7157 if (expr->target().is_identical_to(current_info()->closure())) {
7170 graph()->MarkRecursive(); 7158 graph()->MarkRecursive();
7171 } 7159 }
7172 7160
7173 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { 7161 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) {
7174 // When the target has a custom call IC generator, use the IC, 7162 // When the target has a custom call IC generator, use the IC,
7175 // because it is likely to generate better code. 7163 // because it is likely to generate better code.
7176 HValue* context = environment()->context(); 7164 call = PreProcessCall(New<HCallNamed>(var->name(), argument_count));
7177 call = PreProcessCall(
7178 new(zone()) HCallNamed(context, var->name(), argument_count));
7179 } else { 7165 } else {
7180 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), 7166 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
7181 argument_count)); 7167 argument_count));
7182 } 7168 }
7183 } else { 7169 } else {
7184 HGlobalObject* receiver = Add<HGlobalObject>(); 7170 HGlobalObject* receiver = Add<HGlobalObject>();
7185 PushAndAdd(New<HPushArgument>(receiver)); 7171 PushAndAdd(New<HPushArgument>(receiver));
7186 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7172 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7187 7173
7188 call = New<HCallGlobal>(var->name(), argument_count); 7174 call = New<HCallGlobal>(var->name(), argument_count);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
7242 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize && 7228 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize &&
7243 constructor->initial_map()->InitialPropertiesLength() == 0; 7229 constructor->initial_map()->InitialPropertiesLength() == 0;
7244 } 7230 }
7245 7231
7246 7232
7247 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 7233 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
7248 ASSERT(!HasStackOverflow()); 7234 ASSERT(!HasStackOverflow());
7249 ASSERT(current_block() != NULL); 7235 ASSERT(current_block() != NULL);
7250 ASSERT(current_block()->HasPredecessor()); 7236 ASSERT(current_block()->HasPredecessor());
7251 int argument_count = expr->arguments()->length() + 1; // Plus constructor. 7237 int argument_count = expr->arguments()->length() + 1; // Plus constructor.
7252 HValue* context = environment()->context();
7253 Factory* factory = isolate()->factory(); 7238 Factory* factory = isolate()->factory();
7254 7239
7255 if (FLAG_inline_construct && 7240 if (FLAG_inline_construct &&
7256 expr->IsMonomorphic() && 7241 expr->IsMonomorphic() &&
7257 IsAllocationInlineable(expr->target())) { 7242 IsAllocationInlineable(expr->target())) {
7258 // The constructor function is on the stack in the unoptimized code 7243 // The constructor function is on the stack in the unoptimized code
7259 // during evaluation of the arguments. 7244 // during evaluation of the arguments.
7260 CHECK_ALIVE(VisitForValue(expr->expression())); 7245 CHECK_ALIVE(VisitForValue(expr->expression()));
7261 HValue* function = Top(); 7246 HValue* function = Top();
7262 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7247 CHECK_ALIVE(VisitExpressions(expr->arguments()));
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
7331 HInstruction* instr = current_block()->last(); 7316 HInstruction* instr = current_block()->last();
7332 while (instr != initial_map_value) { 7317 while (instr != initial_map_value) {
7333 HInstruction* prev_instr = instr->previous(); 7318 HInstruction* prev_instr = instr->previous();
7334 instr->DeleteAndReplaceWith(NULL); 7319 instr->DeleteAndReplaceWith(NULL);
7335 instr = prev_instr; 7320 instr = prev_instr;
7336 } 7321 }
7337 initial_map_value->DeleteAndReplaceWith(NULL); 7322 initial_map_value->DeleteAndReplaceWith(NULL);
7338 receiver->DeleteAndReplaceWith(NULL); 7323 receiver->DeleteAndReplaceWith(NULL);
7339 check->DeleteAndReplaceWith(NULL); 7324 check->DeleteAndReplaceWith(NULL);
7340 environment()->SetExpressionStackAt(receiver_index, function); 7325 environment()->SetExpressionStackAt(receiver_index, function);
7341 HInstruction* call = PreProcessCall( 7326 HInstruction* call =
7342 new(zone()) HCallNew(context, function, argument_count)); 7327 PreProcessCall(New<HCallNew>(function, argument_count));
7343 call->set_position(expr->position()); 7328 call->set_position(expr->position());
7344 return ast_context()->ReturnInstruction(call, expr->id()); 7329 return ast_context()->ReturnInstruction(call, expr->id());
7345 } else { 7330 } else {
7346 // The constructor function is both an operand to the instruction and an 7331 // The constructor function is both an operand to the instruction and an
7347 // argument to the construct call. 7332 // argument to the construct call.
7348 Handle<JSFunction> array_function( 7333 Handle<JSFunction> array_function(
7349 isolate()->global_context()->array_function(), isolate()); 7334 isolate()->global_context()->array_function(), isolate());
7350 CHECK_ALIVE(VisitArgument(expr->expression())); 7335 CHECK_ALIVE(VisitArgument(expr->expression()));
7351 HValue* constructor = HPushArgument::cast(Top())->argument(); 7336 HValue* constructor = HPushArgument::cast(Top())->argument();
7352 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7337 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7353 HBinaryCall* call; 7338 HBinaryCall* call;
7354 if (expr->target().is_identical_to(array_function)) { 7339 if (expr->target().is_identical_to(array_function)) {
7355 Handle<Cell> cell = expr->allocation_info_cell(); 7340 Handle<Cell> cell = expr->allocation_info_cell();
7356 Add<HCheckValue>(constructor, array_function); 7341 Add<HCheckValue>(constructor, array_function);
7357 call = new(zone()) HCallNewArray(context, constructor, argument_count, 7342 call = New<HCallNewArray>(constructor, argument_count,
7358 cell, expr->elements_kind()); 7343 cell, expr->elements_kind());
7359 } else { 7344 } else {
7360 call = new(zone()) HCallNew(context, constructor, argument_count); 7345 call = New<HCallNew>(constructor, argument_count);
7361 } 7346 }
7362 Drop(argument_count); 7347 Drop(argument_count);
7363 call->set_position(expr->position()); 7348 call->set_position(expr->position());
7364 return ast_context()->ReturnInstruction(call, expr->id()); 7349 return ast_context()->ReturnInstruction(call, expr->id());
7365 } 7350 }
7366 } 7351 }
7367 7352
7368 7353
7369 // Support for generating inlined runtime functions. 7354 // Support for generating inlined runtime functions.
7370 7355
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
7475 7460
7476 void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { 7461 void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) {
7477 CHECK_ALIVE(VisitForEffect(expr->expression())); 7462 CHECK_ALIVE(VisitForEffect(expr->expression()));
7478 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 7463 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
7479 } 7464 }
7480 7465
7481 7466
7482 void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { 7467 void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) {
7483 CHECK_ALIVE(VisitForTypeOf(expr->expression())); 7468 CHECK_ALIVE(VisitForTypeOf(expr->expression()));
7484 HValue* value = Pop(); 7469 HValue* value = Pop();
7485 HValue* context = environment()->context(); 7470 HInstruction* instr = New<HTypeof>(value);
7486 HInstruction* instr = new(zone()) HTypeof(context, value);
7487 return ast_context()->ReturnInstruction(instr, expr->id()); 7471 return ast_context()->ReturnInstruction(instr, expr->id());
7488 } 7472 }
7489 7473
7490 7474
7491 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { 7475 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) {
7492 if (ast_context()->IsTest()) { 7476 if (ast_context()->IsTest()) {
7493 TestContext* context = TestContext::cast(ast_context()); 7477 TestContext* context = TestContext::cast(ast_context());
7494 VisitForControl(expr->expression(), 7478 VisitForControl(expr->expression(),
7495 context->if_false(), 7479 context->if_false(),
7496 context->if_true()); 7480 context->if_true());
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after
8265 8249
8266 // If the target is not null we have found a known global function that is 8250 // If the target is not null we have found a known global function that is
8267 // assumed to stay the same for this instanceof. 8251 // assumed to stay the same for this instanceof.
8268 if (target.is_null()) { 8252 if (target.is_null()) {
8269 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); 8253 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right);
8270 result->set_position(expr->position()); 8254 result->set_position(expr->position());
8271 return ast_context()->ReturnInstruction(result, expr->id()); 8255 return ast_context()->ReturnInstruction(result, expr->id());
8272 } else { 8256 } else {
8273 Add<HCheckValue>(right, target); 8257 Add<HCheckValue>(right, target);
8274 HInstanceOfKnownGlobal* result = 8258 HInstanceOfKnownGlobal* result =
8275 new(zone()) HInstanceOfKnownGlobal(context, left, target); 8259 New<HInstanceOfKnownGlobal>(left, target);
8276 result->set_position(expr->position()); 8260 result->set_position(expr->position());
8277 return ast_context()->ReturnInstruction(result, expr->id()); 8261 return ast_context()->ReturnInstruction(result, expr->id());
8278 } 8262 }
8279 8263
8280 // Code below assumes that we don't fall through. 8264 // Code below assumes that we don't fall through.
8281 UNREACHABLE(); 8265 UNREACHABLE();
8282 } else if (op == Token::IN) { 8266 } else if (op == Token::IN) {
8283 HValue* function = AddLoadJSBuiltin(Builtins::IN); 8267 HValue* function = AddLoadJSBuiltin(Builtins::IN);
8284 Add<HPushArgument>(left); 8268 Add<HPushArgument>(left);
8285 Add<HPushArgument>(right); 8269 Add<HPushArgument>(right);
8286 // TODO(olivf) InvokeFunction produces a check for the parameter count, 8270 // TODO(olivf) InvokeFunction produces a check for the parameter count,
8287 // even though we are certain to pass the correct number of arguments here. 8271 // even though we are certain to pass the correct number of arguments here.
8288 HInstruction* result = new(zone()) HInvokeFunction(context, function, 2); 8272 HInstruction* result = New<HInvokeFunction>(function, 2);
8289 result->set_position(expr->position()); 8273 result->set_position(expr->position());
8290 return ast_context()->ReturnInstruction(result, expr->id()); 8274 return ast_context()->ReturnInstruction(result, expr->id());
8291 } 8275 }
8292 8276
8293 // Cases handled below depend on collected type feedback. They should 8277 // Cases handled below depend on collected type feedback. They should
8294 // soft deoptimize when there is no type feedback. 8278 // soft deoptimize when there is no type feedback.
8295 if (combined_type->Is(Type::None())) { 8279 if (combined_type->Is(Type::None())) {
8296 Add<HDeoptimize>("Insufficient type feedback for combined type " 8280 Add<HDeoptimize>("Insufficient type feedback for combined type "
8297 "of binary operation", 8281 "of binary operation",
8298 Deoptimizer::SOFT); 8282 Deoptimizer::SOFT);
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
9077 } 9061 }
9078 9062
9079 9063
9080 // Fast support for StringAdd. 9064 // Fast support for StringAdd.
9081 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 9065 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
9082 ASSERT_EQ(2, call->arguments()->length()); 9066 ASSERT_EQ(2, call->arguments()->length());
9083 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9067 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9084 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9068 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9085 HValue* right = Pop(); 9069 HValue* right = Pop();
9086 HValue* left = Pop(); 9070 HValue* left = Pop();
9087 HValue* context = environment()->context(); 9071 HInstruction* result = New<HStringAdd>(left, right, STRING_ADD_CHECK_BOTH);
9088 HInstruction* result = HStringAdd::New(
9089 zone(), context, left, right, STRING_ADD_CHECK_BOTH);
9090 return ast_context()->ReturnInstruction(result, call->id()); 9072 return ast_context()->ReturnInstruction(result, call->id());
9091 } 9073 }
9092 9074
9093 9075
9094 // Fast support for SubString. 9076 // Fast support for SubString.
9095 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 9077 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
9096 ASSERT_EQ(3, call->arguments()->length()); 9078 ASSERT_EQ(3, call->arguments()->length());
9097 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9079 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9098 HValue* context = environment()->context(); 9080 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3);
9099 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3);
9100 Drop(3); 9081 Drop(3);
9101 return ast_context()->ReturnInstruction(result, call->id()); 9082 return ast_context()->ReturnInstruction(result, call->id());
9102 } 9083 }
9103 9084
9104 9085
9105 // Fast support for StringCompare. 9086 // Fast support for StringCompare.
9106 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { 9087 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) {
9107 ASSERT_EQ(2, call->arguments()->length()); 9088 ASSERT_EQ(2, call->arguments()->length());
9108 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9089 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9109 HValue* context = environment()->context(); 9090 HCallStub* result = New<HCallStub>(CodeStub::StringCompare, 2);
9110 HCallStub* result =
9111 new(zone()) HCallStub(context, CodeStub::StringCompare, 2);
9112 Drop(2); 9091 Drop(2);
9113 return ast_context()->ReturnInstruction(result, call->id()); 9092 return ast_context()->ReturnInstruction(result, call->id());
9114 } 9093 }
9115 9094
9116 9095
9117 // Support for direct calls from JavaScript to native RegExp code. 9096 // Support for direct calls from JavaScript to native RegExp code.
9118 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 9097 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
9119 ASSERT_EQ(4, call->arguments()->length()); 9098 ASSERT_EQ(4, call->arguments()->length());
9120 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9099 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9121 HValue* context = environment()->context(); 9100 HCallStub* result = New<HCallStub>(CodeStub::RegExpExec, 4);
9122 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4);
9123 Drop(4); 9101 Drop(4);
9124 return ast_context()->ReturnInstruction(result, call->id()); 9102 return ast_context()->ReturnInstruction(result, call->id());
9125 } 9103 }
9126 9104
9127 9105
9128 // Construct a RegExp exec result with two in-object properties. 9106 // Construct a RegExp exec result with two in-object properties.
9129 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 9107 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) {
9130 ASSERT_EQ(3, call->arguments()->length()); 9108 ASSERT_EQ(3, call->arguments()->length());
9131 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9109 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9132 HValue* context = environment()->context(); 9110 HCallStub* result = New<HCallStub>(CodeStub::RegExpConstructResult, 3);
9133 HCallStub* result =
9134 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3);
9135 Drop(3); 9111 Drop(3);
9136 return ast_context()->ReturnInstruction(result, call->id()); 9112 return ast_context()->ReturnInstruction(result, call->id());
9137 } 9113 }
9138 9114
9139 9115
9140 // Support for fast native caches. 9116 // Support for fast native caches.
9141 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 9117 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
9142 return Bailout(kInlinedRuntimeFunctionGetFromCache); 9118 return Bailout(kInlinedRuntimeFunctionGetFromCache);
9143 } 9119 }
9144 9120
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
9202 HValue* right = Pop(); 9178 HValue* right = Pop();
9203 HValue* left = Pop(); 9179 HValue* left = Pop();
9204 HInstruction* result = HPower::New(zone(), context(), left, right); 9180 HInstruction* result = HPower::New(zone(), context(), left, right);
9205 return ast_context()->ReturnInstruction(result, call->id()); 9181 return ast_context()->ReturnInstruction(result, call->id());
9206 } 9182 }
9207 9183
9208 9184
9209 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { 9185 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) {
9210 ASSERT_EQ(1, call->arguments()->length()); 9186 ASSERT_EQ(1, call->arguments()->length());
9211 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9187 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9212 HValue* context = environment()->context(); 9188 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
9213 HCallStub* result =
9214 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9215 result->set_transcendental_type(TranscendentalCache::SIN); 9189 result->set_transcendental_type(TranscendentalCache::SIN);
9216 Drop(1); 9190 Drop(1);
9217 return ast_context()->ReturnInstruction(result, call->id()); 9191 return ast_context()->ReturnInstruction(result, call->id());
9218 } 9192 }
9219 9193
9220 9194
9221 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) { 9195 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) {
9222 ASSERT_EQ(1, call->arguments()->length()); 9196 ASSERT_EQ(1, call->arguments()->length());
9223 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9197 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9224 HValue* context = environment()->context(); 9198 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
9225 HCallStub* result =
9226 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9227 result->set_transcendental_type(TranscendentalCache::COS); 9199 result->set_transcendental_type(TranscendentalCache::COS);
9228 Drop(1); 9200 Drop(1);
9229 return ast_context()->ReturnInstruction(result, call->id()); 9201 return ast_context()->ReturnInstruction(result, call->id());
9230 } 9202 }
9231 9203
9232 9204
9233 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) { 9205 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) {
9234 ASSERT_EQ(1, call->arguments()->length()); 9206 ASSERT_EQ(1, call->arguments()->length());
9235 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9207 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9236 HValue* context = environment()->context(); 9208 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
9237 HCallStub* result =
9238 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9239 result->set_transcendental_type(TranscendentalCache::TAN); 9209 result->set_transcendental_type(TranscendentalCache::TAN);
9240 Drop(1); 9210 Drop(1);
9241 return ast_context()->ReturnInstruction(result, call->id()); 9211 return ast_context()->ReturnInstruction(result, call->id());
9242 } 9212 }
9243 9213
9244 9214
9245 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) { 9215 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) {
9246 ASSERT_EQ(1, call->arguments()->length()); 9216 ASSERT_EQ(1, call->arguments()->length());
9247 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9217 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9248 HValue* context = environment()->context(); 9218 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
9249 HCallStub* result =
9250 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9251 result->set_transcendental_type(TranscendentalCache::LOG); 9219 result->set_transcendental_type(TranscendentalCache::LOG);
9252 Drop(1); 9220 Drop(1);
9253 return ast_context()->ReturnInstruction(result, call->id()); 9221 return ast_context()->ReturnInstruction(result, call->id());
9254 } 9222 }
9255 9223
9256 9224
9257 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { 9225 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
9258 ASSERT(call->arguments()->length() == 1); 9226 ASSERT(call->arguments()->length() == 1);
9259 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9227 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9260 HValue* value = Pop(); 9228 HValue* value = Pop();
9261 HValue* context = environment()->context(); 9229 HInstruction* result = New<HUnaryMathOperation>(value, kMathSqrt);
9262 HInstruction* result =
9263 HUnaryMathOperation::New(zone(), context, value, kMathSqrt);
9264 return ast_context()->ReturnInstruction(result, call->id()); 9230 return ast_context()->ReturnInstruction(result, call->id());
9265 } 9231 }
9266 9232
9267 9233
9268 // Check whether two RegExps are equivalent 9234 // Check whether two RegExps are equivalent
9269 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { 9235 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) {
9270 return Bailout(kInlinedRuntimeFunctionIsRegExpEquivalent); 9236 return Bailout(kInlinedRuntimeFunctionIsRegExpEquivalent);
9271 } 9237 }
9272 9238
9273 9239
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
9909 if (ShouldProduceTraceOutput()) { 9875 if (ShouldProduceTraceOutput()) {
9910 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9876 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9911 } 9877 }
9912 9878
9913 #ifdef DEBUG 9879 #ifdef DEBUG
9914 graph_->Verify(false); // No full verify. 9880 graph_->Verify(false); // No full verify.
9915 #endif 9881 #endif
9916 } 9882 }
9917 9883
9918 } } // namespace v8::internal 9884 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-check-elimination.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698