| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2513 return NULL; | 2513 return NULL; |
| 2514 } | 2514 } |
| 2515 graph()->EliminateRedundantPhis(); | 2515 graph()->EliminateRedundantPhis(); |
| 2516 if (!graph()->CheckArgumentsPhiUses()) { | 2516 if (!graph()->CheckArgumentsPhiUses()) { |
| 2517 Bailout("Unsupported phi use of arguments"); | 2517 Bailout("Unsupported phi use of arguments"); |
| 2518 return NULL; | 2518 return NULL; |
| 2519 } | 2519 } |
| 2520 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); | 2520 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); |
| 2521 graph()->CollectPhis(); | 2521 graph()->CollectPhis(); |
| 2522 | 2522 |
| 2523 if (graph()->has_osr_loop_entry()) { |
| 2524 const ZoneList<HPhi*>* phis = graph()->osr_loop_entry()->phis(); |
| 2525 for (int j = 0; j < phis->length(); j++) { |
| 2526 HPhi* phi = phis->at(j); |
| 2527 graph()->osr_values()->at(phi->merged_index())->set_incoming_value(phi); |
| 2528 } |
| 2529 } |
| 2530 |
| 2523 HInferRepresentation rep(graph()); | 2531 HInferRepresentation rep(graph()); |
| 2524 rep.Analyze(); | 2532 rep.Analyze(); |
| 2525 | 2533 |
| 2526 graph()->MarkDeoptimizeOnUndefined(); | 2534 graph()->MarkDeoptimizeOnUndefined(); |
| 2527 graph()->InsertRepresentationChanges(); | 2535 graph()->InsertRepresentationChanges(); |
| 2528 | 2536 |
| 2529 graph()->InitializeInferredTypes(); | 2537 graph()->InitializeInferredTypes(); |
| 2530 graph()->Canonicalize(); | 2538 graph()->Canonicalize(); |
| 2531 | 2539 |
| 2532 // Perform common subexpression elimination and loop-invariant code motion. | 2540 // Perform common subexpression elimination and loop-invariant code motion. |
| (...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3085 set_current_block(break_block); | 3093 set_current_block(break_block); |
| 3086 } | 3094 } |
| 3087 } | 3095 } |
| 3088 | 3096 |
| 3089 | 3097 |
| 3090 bool HGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { | 3098 bool HGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { |
| 3091 return statement->OsrEntryId() == info()->osr_ast_id(); | 3099 return statement->OsrEntryId() == info()->osr_ast_id(); |
| 3092 } | 3100 } |
| 3093 | 3101 |
| 3094 | 3102 |
| 3095 void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { | 3103 bool HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { |
| 3096 if (!HasOsrEntryAt(statement)) return; | 3104 if (!HasOsrEntryAt(statement)) return false; |
| 3097 | 3105 |
| 3098 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); | 3106 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); |
| 3099 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); | 3107 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); |
| 3100 HValue* true_value = graph()->GetConstantTrue(); | 3108 HValue* true_value = graph()->GetConstantTrue(); |
| 3101 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); | 3109 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); |
| 3102 current_block()->Finish(test); | 3110 current_block()->Finish(test); |
| 3103 | 3111 |
| 3104 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 3112 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
| 3105 non_osr_entry->Goto(loop_predecessor); | 3113 non_osr_entry->Goto(loop_predecessor); |
| 3106 | 3114 |
| 3107 set_current_block(osr_entry); | 3115 set_current_block(osr_entry); |
| 3108 int osr_entry_id = statement->OsrEntryId(); | 3116 int osr_entry_id = statement->OsrEntryId(); |
| 3109 int first_expression_index = environment()->first_expression_index(); | 3117 int first_expression_index = environment()->first_expression_index(); |
| 3110 int length = environment()->length(); | 3118 int length = environment()->length(); |
| 3119 ZoneList<HUnknownOSRValue*>* osr_values = |
| 3120 new(zone()) ZoneList<HUnknownOSRValue*>(length); |
| 3121 |
| 3111 for (int i = 0; i < first_expression_index; ++i) { | 3122 for (int i = 0; i < first_expression_index; ++i) { |
| 3112 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3123 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
| 3113 AddInstruction(osr_value); | 3124 AddInstruction(osr_value); |
| 3114 environment()->Bind(i, osr_value); | 3125 environment()->Bind(i, osr_value); |
| 3126 osr_values->Add(osr_value); |
| 3115 } | 3127 } |
| 3116 | 3128 |
| 3117 if (first_expression_index != length) { | 3129 if (first_expression_index != length) { |
| 3118 environment()->Drop(length - first_expression_index); | 3130 environment()->Drop(length - first_expression_index); |
| 3119 for (int i = first_expression_index; i < length; ++i) { | 3131 for (int i = first_expression_index; i < length; ++i) { |
| 3120 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3132 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
| 3121 AddInstruction(osr_value); | 3133 AddInstruction(osr_value); |
| 3122 environment()->Push(osr_value); | 3134 environment()->Push(osr_value); |
| 3135 osr_values->Add(osr_value); |
| 3123 } | 3136 } |
| 3124 } | 3137 } |
| 3125 | 3138 |
| 3139 graph()->set_osr_values(osr_values); |
| 3140 |
| 3126 AddSimulate(osr_entry_id); | 3141 AddSimulate(osr_entry_id); |
| 3127 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 3142 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
| 3128 HContext* context = new(zone()) HContext; | 3143 HContext* context = new(zone()) HContext; |
| 3129 AddInstruction(context); | 3144 AddInstruction(context); |
| 3130 environment()->BindContext(context); | 3145 environment()->BindContext(context); |
| 3131 current_block()->Goto(loop_predecessor); | 3146 current_block()->Goto(loop_predecessor); |
| 3132 loop_predecessor->SetJoinId(statement->EntryId()); | 3147 loop_predecessor->SetJoinId(statement->EntryId()); |
| 3133 set_current_block(loop_predecessor); | 3148 set_current_block(loop_predecessor); |
| 3149 return true; |
| 3134 } | 3150 } |
| 3135 | 3151 |
| 3136 | 3152 |
| 3137 void HGraphBuilder::VisitLoopBody(IterationStatement* stmt, | 3153 void HGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
| 3138 HBasicBlock* loop_entry, | 3154 HBasicBlock* loop_entry, |
| 3139 BreakAndContinueInfo* break_info) { | 3155 BreakAndContinueInfo* break_info) { |
| 3140 BreakAndContinueScope push(break_info, this); | 3156 BreakAndContinueScope push(break_info, this); |
| 3141 AddSimulate(stmt->StackCheckId()); | 3157 AddSimulate(stmt->StackCheckId()); |
| 3142 HValue* context = environment()->LookupContext(); | 3158 HValue* context = environment()->LookupContext(); |
| 3143 HStackCheck* stack_check = | 3159 HStackCheck* stack_check = |
| 3144 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); | 3160 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); |
| 3145 AddInstruction(stack_check); | 3161 AddInstruction(stack_check); |
| 3146 ASSERT(loop_entry->IsLoopHeader()); | 3162 ASSERT(loop_entry->IsLoopHeader()); |
| 3147 loop_entry->loop_information()->set_stack_check(stack_check); | 3163 loop_entry->loop_information()->set_stack_check(stack_check); |
| 3148 CHECK_BAILOUT(Visit(stmt->body())); | 3164 CHECK_BAILOUT(Visit(stmt->body())); |
| 3149 } | 3165 } |
| 3150 | 3166 |
| 3151 | 3167 |
| 3152 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 3168 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 3153 ASSERT(!HasStackOverflow()); | 3169 ASSERT(!HasStackOverflow()); |
| 3154 ASSERT(current_block() != NULL); | 3170 ASSERT(current_block() != NULL); |
| 3155 ASSERT(current_block()->HasPredecessor()); | 3171 ASSERT(current_block()->HasPredecessor()); |
| 3156 ASSERT(current_block() != NULL); | 3172 ASSERT(current_block() != NULL); |
| 3157 PreProcessOsrEntry(stmt); | 3173 bool osr_entry = PreProcessOsrEntry(stmt); |
| 3158 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 3174 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| 3159 current_block()->Goto(loop_entry); | 3175 current_block()->Goto(loop_entry); |
| 3160 set_current_block(loop_entry); | 3176 set_current_block(loop_entry); |
| 3177 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| 3161 | 3178 |
| 3162 BreakAndContinueInfo break_info(stmt); | 3179 BreakAndContinueInfo break_info(stmt); |
| 3163 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 3180 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); |
| 3164 HBasicBlock* body_exit = | 3181 HBasicBlock* body_exit = |
| 3165 JoinContinue(stmt, current_block(), break_info.continue_block()); | 3182 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 3166 HBasicBlock* loop_successor = NULL; | 3183 HBasicBlock* loop_successor = NULL; |
| 3167 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { | 3184 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { |
| 3168 set_current_block(body_exit); | 3185 set_current_block(body_exit); |
| 3169 // The block for a true condition, the actual predecessor block of the | 3186 // The block for a true condition, the actual predecessor block of the |
| 3170 // back edge. | 3187 // back edge. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3189 break_info.break_block()); | 3206 break_info.break_block()); |
| 3190 set_current_block(loop_exit); | 3207 set_current_block(loop_exit); |
| 3191 } | 3208 } |
| 3192 | 3209 |
| 3193 | 3210 |
| 3194 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | 3211 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
| 3195 ASSERT(!HasStackOverflow()); | 3212 ASSERT(!HasStackOverflow()); |
| 3196 ASSERT(current_block() != NULL); | 3213 ASSERT(current_block() != NULL); |
| 3197 ASSERT(current_block()->HasPredecessor()); | 3214 ASSERT(current_block()->HasPredecessor()); |
| 3198 ASSERT(current_block() != NULL); | 3215 ASSERT(current_block() != NULL); |
| 3199 PreProcessOsrEntry(stmt); | 3216 bool osr_entry = PreProcessOsrEntry(stmt); |
| 3200 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 3217 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| 3201 current_block()->Goto(loop_entry); | 3218 current_block()->Goto(loop_entry); |
| 3202 set_current_block(loop_entry); | 3219 set_current_block(loop_entry); |
| 3220 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| 3221 |
| 3203 | 3222 |
| 3204 // If the condition is constant true, do not generate a branch. | 3223 // If the condition is constant true, do not generate a branch. |
| 3205 HBasicBlock* loop_successor = NULL; | 3224 HBasicBlock* loop_successor = NULL; |
| 3206 if (!stmt->cond()->ToBooleanIsTrue()) { | 3225 if (!stmt->cond()->ToBooleanIsTrue()) { |
| 3207 HBasicBlock* body_entry = graph()->CreateBasicBlock(); | 3226 HBasicBlock* body_entry = graph()->CreateBasicBlock(); |
| 3208 loop_successor = graph()->CreateBasicBlock(); | 3227 loop_successor = graph()->CreateBasicBlock(); |
| 3209 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); | 3228 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); |
| 3210 if (body_entry->HasPredecessor()) { | 3229 if (body_entry->HasPredecessor()) { |
| 3211 body_entry->SetJoinId(stmt->BodyId()); | 3230 body_entry->SetJoinId(stmt->BodyId()); |
| 3212 set_current_block(body_entry); | 3231 set_current_block(body_entry); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3234 | 3253 |
| 3235 | 3254 |
| 3236 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { | 3255 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { |
| 3237 ASSERT(!HasStackOverflow()); | 3256 ASSERT(!HasStackOverflow()); |
| 3238 ASSERT(current_block() != NULL); | 3257 ASSERT(current_block() != NULL); |
| 3239 ASSERT(current_block()->HasPredecessor()); | 3258 ASSERT(current_block()->HasPredecessor()); |
| 3240 if (stmt->init() != NULL) { | 3259 if (stmt->init() != NULL) { |
| 3241 CHECK_ALIVE(Visit(stmt->init())); | 3260 CHECK_ALIVE(Visit(stmt->init())); |
| 3242 } | 3261 } |
| 3243 ASSERT(current_block() != NULL); | 3262 ASSERT(current_block() != NULL); |
| 3244 PreProcessOsrEntry(stmt); | 3263 bool osr_entry = PreProcessOsrEntry(stmt); |
| 3245 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 3264 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| 3246 current_block()->Goto(loop_entry); | 3265 current_block()->Goto(loop_entry); |
| 3247 set_current_block(loop_entry); | 3266 set_current_block(loop_entry); |
| 3267 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| 3248 | 3268 |
| 3249 HBasicBlock* loop_successor = NULL; | 3269 HBasicBlock* loop_successor = NULL; |
| 3250 if (stmt->cond() != NULL) { | 3270 if (stmt->cond() != NULL) { |
| 3251 HBasicBlock* body_entry = graph()->CreateBasicBlock(); | 3271 HBasicBlock* body_entry = graph()->CreateBasicBlock(); |
| 3252 loop_successor = graph()->CreateBasicBlock(); | 3272 loop_successor = graph()->CreateBasicBlock(); |
| 3253 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); | 3273 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); |
| 3254 if (body_entry->HasPredecessor()) { | 3274 if (body_entry->HasPredecessor()) { |
| 3255 body_entry->SetJoinId(stmt->BodyId()); | 3275 body_entry->SetJoinId(stmt->BodyId()); |
| 3256 set_current_block(body_entry); | 3276 set_current_block(body_entry); |
| 3257 } | 3277 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3329 Push(start_index); | 3349 Push(start_index); |
| 3330 | 3350 |
| 3331 HInstruction* index_cache = AddInstruction( | 3351 HInstruction* index_cache = AddInstruction( |
| 3332 new(zone()) HForInCacheArray( | 3352 new(zone()) HForInCacheArray( |
| 3333 enumerable, | 3353 enumerable, |
| 3334 map, | 3354 map, |
| 3335 DescriptorArray::kEnumCacheBridgeIndicesCacheIndex)); | 3355 DescriptorArray::kEnumCacheBridgeIndicesCacheIndex)); |
| 3336 HForInCacheArray::cast(array)->set_index_cache( | 3356 HForInCacheArray::cast(array)->set_index_cache( |
| 3337 HForInCacheArray::cast(index_cache)); | 3357 HForInCacheArray::cast(index_cache)); |
| 3338 | 3358 |
| 3339 PreProcessOsrEntry(stmt); | 3359 bool osr_entry = PreProcessOsrEntry(stmt); |
| 3340 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 3360 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| 3341 current_block()->Goto(loop_entry); | 3361 current_block()->Goto(loop_entry); |
| 3342 set_current_block(loop_entry); | 3362 set_current_block(loop_entry); |
| 3363 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| 3343 | 3364 |
| 3344 HValue* index = environment()->ExpressionStackAt(0); | 3365 HValue* index = environment()->ExpressionStackAt(0); |
| 3345 HValue* limit = environment()->ExpressionStackAt(1); | 3366 HValue* limit = environment()->ExpressionStackAt(1); |
| 3346 | 3367 |
| 3347 // Check that we still have more keys. | 3368 // Check that we still have more keys. |
| 3348 HCompareIDAndBranch* compare_index = | 3369 HCompareIDAndBranch* compare_index = |
| 3349 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); | 3370 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); |
| 3350 compare_index->SetInputRepresentation(Representation::Integer32()); | 3371 compare_index->SetInputRepresentation(Representation::Integer32()); |
| 3351 | 3372 |
| 3352 HBasicBlock* loop_body = graph()->CreateBasicBlock(); | 3373 HBasicBlock* loop_body = graph()->CreateBasicBlock(); |
| (...skipping 4772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8125 } | 8146 } |
| 8126 } | 8147 } |
| 8127 | 8148 |
| 8128 #ifdef DEBUG | 8149 #ifdef DEBUG |
| 8129 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 8150 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 8130 if (allocator_ != NULL) allocator_->Verify(); | 8151 if (allocator_ != NULL) allocator_->Verify(); |
| 8131 #endif | 8152 #endif |
| 8132 } | 8153 } |
| 8133 | 8154 |
| 8134 } } // namespace v8::internal | 8155 } } // namespace v8::internal |
| OLD | NEW |